2016-12-12 13 views
13

Tôi đang gặp phải rò rỉ bộ nhớ và ở đây có một số chi tiết.Vùng heap Java và kích thước heap sau khi phân tích đống khác nhau

At the time of after-leak, 
    - top shows 50GB memory as residential 
    - heap dump file size is 25GB 
    - eclipse MAT analyzer tells me the heap size is 10GB 

At the time of before-leak, 
    - top shows 30GB memory as residential 
    - heap dump file size is 20GB 
    - eclipse MAT analyzer tells me the heap size is 10GB 

Tôi khá ngạc nhiên khi thấy sự khác biệt giữa kích thước heap-dump và kích thước heap thực tế. Tôi đoán rằng sự khác biệt giữa đầu và heap là khả năng của đống thu rác và vùng heap bản địa. Nhưng, kích thước tệp kết xuất đống và kích thước heap thực tế (từ máy phân tích MAT eclipse) có thể khác nhau như thế nào?

Bất kỳ thông tin chi tiết nào về vấn đề này?

UPDATE/ĐÁP

Một số đề nghị được sử dụng jcmd (https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr007.html) như các trang web nói "Native Memory Theo dõi". Tuy nhiên, nếu bạn đọc kỹ trang, bạn sẽ thấy

Since NMT doesn't track memory allocations by non-JVM code, 
you may have to use tools supported by the operating system 
to detect memory leaks in native code. 

Vì vậy, trong trường hợp rò rỉ bên trong thư viện gốc, jcmd không phải là một tùy chọn.

Sau khi thu thập thông tin từ Internets trong nhiều ngày và thử các trình đơn khác nhau, hiệu quả nhất cho vấn đề này là sử dụng jemalloc profiler.

Trang này đã giúp tôi rất nhiều! https://gdstechnology.blog.gov.uk/2015/12/11/using-jemalloc-to-get-to-the-bottom-of-a-memory-leak/

+1

Xem http://stackoverflow.com/questions/36872551/relation-between-memory-host-and-memory-arguments-xms-and-xmx-from-java/ 36927242 # 36927242 – apangin

+1

các liên kết thú vị khác https://plumbr.eu/blog/memory-leaks/why-does-my-java-process-consume-more-memory-than-xmx và https://blogs.oracle.com/jrockit/entry/why_is_my_jvm_process_larger_t –

Trả lời

2

Tôi đã gặp phải tình huống tương tự. Sự khác biệt (kích thước tệp HPROF - Kích thước của heap được chỉ ra bởi MAT) là rác hiệu quả (đối tượng không thể truy cập). Đối tượng không thể truy cập Biểu đồ trong MAT sẽ trợ giúp ở đây.

jmap -F -dump:live,format=b,file=<file_name.hprof> <process_id> sẽ chỉ đổ các đối tượng trực tiếp và KHÔNG bị cắt xén.

+0

Cảm ơn tôi thấy điều đó ngay bây giờ. Nhưng tôi vẫn cần phải kno sự khác biệt giữa kích thước dân cư và kích thước heap. – jaeyong

3

top và các công cụ cấp hệ điều hành khác cho biết quá trình JVM của bạn sử dụng bao nhiêu bộ nhớ hệ thống. Java heap, được xác định bởi -Xmx tùy chọn dòng lệnh, chỉ là một phần của bộ nhớ đó. Ngoài JVM heap cần một số bộ nhớ cho chính nó. Sau đó, có các chủ đề java, mỗi chủ đề đòi hỏi một lượng bộ nhớ nhất định. Và Metaspace/thế hệ vĩnh viễn. Và một số người khác. Bạn có thể đọc this blog postthis SO answer để biết thêm thông tin.

Về kích thước tệp kết xuất và kích thước heap thực tế, câu trả lời của @ arnab-biswas chắc chắn là đúng. MAT báo cáo kích thước của đống thực sự được sử dụng, được tiêu thụ bởi các đối tượng trực tiếp. Nhưng đống đống chứa toàn bộ đống, kể cả rác.

+0

Cảm ơn câu trả lời. Có vẻ như bạn đang đề xuất NativeMemoryTracking, nhưng điều này không thực sự theo dõi phân bổ bộ nhớ từ chính thư viện gốc. Nó chỉ có thể theo dõi việc phân bổ mã java theo https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr007.html này. "Vì NMT không theo dõi phân bổ bộ nhớ bằng mã không phải JVM, bạn có thể phải sử dụng các công cụ được hệ điều hành hỗ trợ để phát hiện rò rỉ bộ nhớ trong mã gốc." – jaeyong

0

Để theo dõi bộ nhớ riêng, bạn cần khởi động ứng dụng của mình với -XX:NativeMemoryTracking=summary hoặc -XX:NativeMemoryTracking=detail. Lưu ý rằng có một hình phạt hiệu suất, do đó, suy nghĩ hai lần trước khi làm nó trong sản xuất.

Khi theo dõi bộ nhớ hoạt động, bạn có thể sử dụng jcmd <pid> VM.native_memory summary. Ngoài ra còn có các lệnh khác, hãy kiểm tra https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr007.html hoặc tìm kiếm theo dõi bộ nhớ riêng.

CHỈNH SỬA: Tôi không theo các liên kết trước khi trả lời, bạn có thể tìm kiếm một cái gì đó như https://github.com/jeffgriffith/native-jvm-leaks thay thế.

0

Heap dump: Kết xuất vùng lưu trữ là ảnh chụp nhanh bộ nhớ của quá trình Java tại một thời điểm nhất định.Có các định dạng khác nhau để lưu trữ dữ liệu này, và tùy thuộc vào định dạng nó có thể chứa các phần thông tin khác nhau, nhưng nhìn chung ảnh chụp chứa thông tin về các đối tượng java và các lớp trong heap tại thời điểm ảnh chụp được kích hoạt. Thông thường, một GC đầy đủ được kích hoạt trước khi đống kết xuất được viết để nó chứa thông tin về các đối tượng còn lại.

Để biết thông tin liên quan đến MAT tìm thấy ở đây http://help.eclipse.org/neon/index.jsp?topic=/org.eclipse.mat.ui.help/welcome.html

0

Bạn đang yêu cầu một câu trả lời rút ra từ các nguồn đáng tin cậy/chính thức. Hãy để tôi thử.

1) tại sao bộ nhớ được tiêu thụ bởi quy trình JVM của tôi (được hiển thị bằng đầu) lớn hơn kích thước heap ?

Do tổng mức tiêu thụ bộ nhớ của quy trình JVM bao gồm nhiều thứ hơn chỉ là vùng heap Java. Một vài ví dụ:

- Generated (JIT:ed) code 
- Loaded libraries (including jar and class files) 
- Control structures for the java heap 
- Thread Stacks 
- User native memory (malloc:ed in JNI) 

đáng tin cậy/nguồn chính thức: Run-Time Data Areasthis blog post

2) tại sao là kích thước khối xếp bãi lớn hơn nhiều so với báo cáo những gì MAT?

Vì MAT không hiển thị toàn bộ vùng. Trong quá trình tạo chỉ mục, Bộ phân tích bộ nhớ loại bỏ các đối tượng không thể truy cập được vì các thuật toán thu gom rác khác nhau có xu hướng để lại một số rác phía sau.

đáng tin cậy/nguồn chính thức: MemoryAnalyzer/FAQ

Các vấn đề liên quan