Công cụ phân tích kết xuất đống Java lớn


80

Tôi có một kết xuất đống HotSpot JVM mà tôi muốn phân tích. Máy ảo đã chạy với -Xmx31gvà tệp kết xuất heap có dung lượng 48 GB.

  • Tôi thậm chí sẽ không thử jhat, vì nó yêu cầu khoảng năm lần bộ nhớ heap (trong trường hợp của tôi là 240 GB) và rất chậm.
  • Eclipse MAT gặp sự cố ArrayIndexOutOfBoundsExceptionsau khi phân tích kết xuất đống trong vài giờ.

Những công cụ nào khác có sẵn cho nhiệm vụ đó? Tốt nhất là một bộ công cụ dòng lệnh, bao gồm một chương trình chuyển đổi đống đổ đống thành các cấu trúc dữ liệu hiệu quả để phân tích, kết hợp với một số công cụ khác hoạt động trên dữ liệu có cấu trúc trước.


Bạn có chắc chắn kết xuất không bị hỏng và bạn đang sử dụng phiên bản mới hơn của DTFJ JAR? Các ArrayIndexOutOfBoundsExceptiontính năng trong ít nhất hai lỗi . Tôi nói rõ điều này vì bạn đã không báo cáo OOME khi chạy MAT, có một bản sửa lỗi khác .
Vineet Reynolds

jhat sử dụng heapMap để lưu trữ các đối tượng đã đọc, số đối tượng này tăng theo cấp số nhân với số lượng đối tượng được lưu trữ trong heap. Một tùy chọn là thay đổi khai báo từ heapMap thành TreeMap và chạy kích thước heap của jhat ít nhất bằng quy trình của bạn.
codeDr

Câu trả lời:


79

Thông thường, những gì tôi sử dụng được ParseHeapDump.shbao gồm trong Trình phân tích bộ nhớ Eclipse và được mô tả ở đây , và tôi thực hiện điều đó trên một máy chủ tăng cường hơn của chúng tôi (tải xuống và sao chép qua bản phân phối .zip linux, giải nén ở đó). Tập lệnh shell cần ít tài nguyên hơn so với phân tích cú pháp heap từ GUI, ngoài ra bạn có thể chạy nó trên máy chủ mạnh mẽ của mình với nhiều tài nguyên hơn (bạn có thể phân bổ nhiều tài nguyên hơn bằng cách thêm thứ gì đó giống như -vmargs -Xmx40g -XX:-UseGCOverheadLimitvào cuối dòng cuối cùng của tập lệnh. Ví dụ: dòng cuối cùng của tệp đó có thể trông như thế này sau khi sửa đổi

./MemoryAnalyzer -consolelog -application org.eclipse.mat.api.parse "$@" -vmargs -Xmx40g -XX:-UseGCOverheadLimit

Chạy nó như ./path/to/ParseHeapDump.sh ../today_heap_dump/jvm.hprof

Sau khi thành công, nó tạo ra một số tệp "chỉ mục" bên cạnh tệp .hprof.

Sau khi tạo các chỉ số, tôi cố gắng tạo các báo cáo từ đó và quét các báo cáo đó đến các máy cục bộ của mình và thử xem liệu tôi có thể tìm ra thủ phạm chỉ bằng cách đó không (không chỉ báo cáo, không phải chỉ số). Đây là hướng dẫn về cách tạo báo cáo .

Báo cáo mẫu:

./ParseHeapDump.sh ../today_heap_dump/jvm.hprof org.eclipse.mat.api:suspects

Các tùy chọn báo cáo khác:

org.eclipse.mat.api:overvieworg.eclipse.mat.api:top_components

Nếu những báo cáo đó không đủ và nếu tôi cần đào thêm (tức là hãy nói qua oql), tôi quét các chỉ mục cũng như tệp hprof vào máy cục bộ của mình và sau đó mở kết xuất heap (với các chỉ số trong cùng một thư mục như kết xuất đống) với Eclipse MAT GUI của tôi. Từ đó, nó không cần quá nhiều bộ nhớ để chạy.

CHỈNH SỬA: Tôi chỉ muốn thêm hai ghi chú:

  • Theo như tôi biết, chỉ có phần tạo ra các chỉ số là phần bộ nhớ chuyên sâu của Eclipse MAT. Sau khi bạn có các chỉ mục, hầu hết quá trình xử lý của bạn từ Eclipse MAT sẽ không cần nhiều bộ nhớ như vậy.
  • Làm điều này trên một tập lệnh shell có nghĩa là tôi có thể thực hiện nó trên một máy chủ không đầu (và tôi cũng thường làm điều đó trên một máy chủ không đầu, vì chúng thường là những máy chủ mạnh nhất). Và nếu bạn có một máy chủ có thể tạo ra một kết xuất heap với kích thước đó, rất có thể, bạn có một máy chủ khác cũng có thể xử lý nhiều như vậy về kết xuất heap.

4
Lưu ý quan trọng: chỉ ParseHeapDump.shđược đóng gói với phiên bản Linux, không phải phiên bản OSX - eclipse.org/mat/downloads.php
Christopher

Khi tôi thử điều này (ssh'd để bash trên hộp linux), nó không thành công ngay lập tức với "Không thể khởi tạo GTK +". Vì vậy, có vẻ như (phiên bản hiện tại, 2016-04-15) vẫn nghĩ rằng nó đang nói chuyện với một giao diện người dùng (?).
Charles Roth

2
Rất tiếc, các phiên bản mới hơn của ParseHeapDump.sh muốn chạy trực tiếp ./MemoryAnalyzer. Tôi đang thử nghiệm chạy trình khởi chạy trực tiếp với java, cho đến nay dường như nó đang hoạt động, ví dụ: java -Xmx16g -Xms16g -jar plugins / org.eclipse.equinox.launcher_1.3.100.v20150511-1540.jar -consoleLog -consolelog -application org.eclipse.mat.api.parse "$ @"
Charles Roth

Có vẻ như bạn có thể sử dụng nó trên OS X bằng cách tải xuống cả hai phiên bản Linux và OSX, sau đó sao chép ParseHeapDump.sh vào cùng một tệp với tệp MemoryAnalyze của bạn (trong trường hợp của tôi là ~ / Downloads / mat.app / Contents / MacOS) và sửa đổi và chạy nó ở đó. Hoặc chạy nó trên một số máy chủ từ xa tất nhiên, thông qua SSH :)
rogerdpack

Đã mở một kết xuất heap 2GB với Eclipse Memory Analyzer GUI sử dụng bộ nhớ không quá 500MB. Các tệp chỉ mục đã được tạo nhanh khi mở tệp (mất ~ 30 giây). Có thể họ đã cải tiến công cụ. Nó thuận lợi hơn là sao chép các tệp lớn qua lại, nếu nó thực sự hoạt động theo cách này. Dung lượng bộ nhớ nhỏ ngay cả khi không có bất kỳ tiện ích giao diện điều khiển nào là một điểm cộng lớn đối với tôi. Nhưng thành thật mà nói, tôi đã không thử nó với dung lượng thực sự lớn (50+ GB). Rất thú vị là cần bao nhiêu bộ nhớ để mở và phân tích những bãi rác lớn như vậy bằng công cụ này.
Ruslan Stelmachenko

6

Câu trả lời được chấp nhận cho câu hỏi liên quan này sẽ cung cấp một khởi đầu tốt cho bạn (sử dụng biểu đồ jmap trực tiếp thay vì kết xuất đống):

Phương pháp tìm rò rỉ bộ nhớ trong các kết xuất heap lớn của Java

Hầu hết các trình phân tích heap khác (tôi sử dụng http://www.alphaworks.ibm.com/tech/heapanalyzer của IBM ) yêu cầu ít nhất một tỷ lệ phần trăm RAM nhiều hơn heap nếu bạn đang mong đợi một công cụ GUI đẹp.

Ngoài ra, nhiều nhà phát triển sử dụng các cách tiếp cận thay thế, chẳng hạn như phân tích ngăn xếp trực tiếp để có ý tưởng về những gì đang xảy ra.

Mặc dù tôi phải đặt câu hỏi tại sao đống của bạn lại lớn như vậy? Hiệu quả đối với việc phân bổ và thu gom rác phải rất lớn. Tôi cá rằng một tỷ lệ phần trăm lớn những gì trong heap của bạn sẽ thực sự được lưu trữ trong cơ sở dữ liệu / bộ nhớ cache liên tục, v.v.


5

Tôi khuyên bạn nên thử YourKit. Nó thường cần ít bộ nhớ hơn một chút so với kích thước kết xuất heap (nó lập chỉ mục nó và sử dụng thông tin đó để truy xuất những gì bạn muốn)


4

Một số tùy chọn khác:

Người này http://blog.ragozin.info/2015/02/programatic-heapdump-analysis.html

đã viết một trình phân tích đống Netbeans tùy chỉnh chỉ hiển thị giao diện "kiểu truy vấn" thông qua tệp kết xuất đống, thay vì thực sự tải tệp vào bộ nhớ.

https://github.com/aragozin/jvm-tools/tree/master/hprof-heap

Mặc dù tôi không biết liệu "ngôn ngữ truy vấn của anh ấy" có tốt hơn OQL nhật thực được đề cập trong câu trả lời được chấp nhận ở đây hay không.

JProfiler 8.1 ($ 499 cho giấy phép người dùng) cũng được cho là có thể truyền qua các đống lớn mà không cần sử dụng nhiều tiền.


Trên thực tế, hoạt động trên một bãi chứa lớn, không giống như github.com/on-site/fasthat . Đẹp!
Jesse Glick vào

4

Bước đầu tiên: tăng dung lượng RAM bạn đang phân bổ cho MAT. Theo mặc định, nó không nhiều và không thể mở các tệp lớn.

Trong trường hợp sử dụng MAT trên MAC (OSX), bạn sẽ có tệp MemoryAnalyzer.ini tệp trong MemoryAnalyzer.app/Contents/MacOS. Tôi không thể thực hiện các điều chỉnh đối với tệp đó và yêu cầu chúng "lấy". Thay vào đó, bạn có thể tạo một lệnh khởi động / tập lệnh shell được sửa đổi dựa trên nội dung của tệp này và chạy nó từ thư mục đó. Trong trường hợp của tôi, tôi muốn heap 20 GB:

./MemoryAnalyzer -vmargs -Xmx20g --XX:-UseGCOverheadLimit ... other params desired

Chỉ cần chạy lệnh / tập lệnh này từ thư mục Contents / MacOS thông qua thiết bị đầu cuối, để khởi động GUI với nhiều RAM hơn.


Cảm ơn. DLd tiện ích ngày hôm nay. Đã thử chạy bằng cách nhấp 2 lần và nó đã báo lỗi. Đã nhìn vào nhật ký, không thể tạo tệp dữ liệu và nói sử dụng công tắc. Mở gói .app và tìm thấy MemoryAnalyzer.ini trong thư mục Eclipse \, không phải \ MacOS. A-ha! Vì vậy, tôi đã giải nén tất cả các tệp cục bộ và làm như bạn đề xuất. Tôi đã tạo một tệp .sh trong \ MacOS và chuyển các lệnh trong Eclipse \ MemoryAnalyzer.ini vào đó dưới dạng một dòng đơn phẳng. Tệp đã lưu. Chạy tệp .sh từ MacOS \ trên dòng lệnh và thì nó đã hoạt động.
Matt Campbell

2

Một công cụ không quá nổi tiếng - http://dr-brenschede.de/bheapsampler/ hoạt động tốt cho các đống lớn. Nó hoạt động bằng cách lấy mẫu nên không cần phải đọc toàn bộ, mặc dù hơi phức tạp.


Thật không may, nó nói "vấn đề phổ biến: hết bộ nhớ: Tăng -Xmx lên 2/3 kích thước kết xuất" nhưng tôi cho rằng nếu bạn có đủ RAM hoặc có thể chạy nó trên một máy chủ có đủ, điều đó có thể là đủ, cảm ơn !
rogerdpack

2

Bản dựng ảnh chụp nhanh mới nhất của Eclipse Memory Analyzer có một cơ sở để loại bỏ ngẫu nhiên một tỷ lệ đối tượng nhất định để giảm mức tiêu thụ bộ nhớ và cho phép phân tích các đối tượng còn lại. Xem Bug 563960bản dựng ảnh chụp nhanh hàng đêm để kiểm tra cơ sở này trước khi nó được đưa vào bản phát hành tiếp theo của MAT.


1

Đây không phải là giải pháp dòng lệnh, tuy nhiên tôi thích các công cụ:

Sao chép kết xuất đống vào một máy chủ đủ lớn để lưu trữ nó. Rất có thể máy chủ gốc có thể được sử dụng.

Nhập máy chủ qua ssh -Xđể chạy công cụ đồ họa từ xa và sử dụng jvisualvmtừ thư mục nhị phân Java để tải .hproftệp của kết xuất đống.

Công cụ không tải toàn bộ kết xuất heap vào bộ nhớ cùng một lúc, nhưng tải các bộ phận khi chúng được yêu cầu. Tất nhiên, nếu bạn nhìn đủ xung quanh tệp, bộ nhớ cần thiết cuối cùng sẽ đạt đến kích thước của kết xuất đống.


0

Hãy thử sử dụng jprofiler, nó hoạt động tốt trong việc phân tích .hprof lớn, tôi đã thử với tệp có kích thước khoảng 22 GB.

https://www.ej-technologies.com/products/jprofiler/overview.html

0

Tôi đã xem qua một công cụ thú vị có tên là JXray. Nó cung cấp giấy phép thử nghiệm đánh giá hạn chế. Tìm thấy bộ nhớ bị rò rỉ rất hữu ích. Bạn có thể cho nó một shot.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.