2015-07-01 16 views
17

Khi chạy một ứng dụng Java (trong YARN) với theo dõi bộ nhớ riêng được bật (-XX:NativeMemoryTracking=detail xem https://docs.oracle.com/javase/8/docs/technotes/guides/vm/nmt-8.htmlhttps://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr007.html), tôi có thể xem bộ nhớ JVM đang sử dụng bao nhiêu bộ nhớ trong các danh mục khác nhau.Tại sao JVM báo cáo bộ nhớ cam kết nhiều hơn kích thước thiết lập quy trình cư trú của Linux?

Ứng dụng của tôi trên jdk 1.8.0_45 show:

 
Native Memory Tracking: 

Total: reserved=4023326KB, committed=2762382KB 
-     Java Heap (reserved=1331200KB, committed=1331200KB) 
          (mmap: reserved=1331200KB, committed=1331200KB) 

-      Class (reserved=1108143KB, committed=64559KB) 
          (classes #8621) 
          (malloc=6319KB #17371) 
          (mmap: reserved=1101824KB, committed=58240KB) 

-     Thread (reserved=1190668KB, committed=1190668KB) 
          (thread #1154) 
          (stack: reserved=1185284KB, committed=1185284KB) 
          (malloc=3809KB #5771) 
          (arena=1575KB #2306) 

-      Code (reserved=255744KB, committed=38384KB) 
          (malloc=6144KB #8858) 
          (mmap: reserved=249600KB, committed=32240KB) 

-      GC (reserved=54995KB, committed=54995KB) 
          (malloc=5775KB #217) 
          (mmap: reserved=49220KB, committed=49220KB) 

-     Compiler (reserved=267KB, committed=267KB) 
          (malloc=137KB #333) 
          (arena=131KB #3) 

-     Internal (reserved=65106KB, committed=65106KB) 
          (malloc=65074KB #29652) 
          (mmap: reserved=32KB, committed=32KB) 

-     Symbol (reserved=13622KB, committed=13622KB) 
          (malloc=12016KB #128199) 
          (arena=1606KB #1) 

- Native Memory Tracking (reserved=3361KB, committed=3361KB) 
          (malloc=287KB #3994) 
          (tracking overhead=3075KB) 

-    Arena Chunk (reserved=220KB, committed=220KB) 
          (malloc=220KB) 

Điều này cho thấy 2.7GB bộ nhớ cam kết, trong đó có 1,3GB đống phân bổ và gần như 1.2 GB của phân bổ ngăn xếp chủ đề (sử dụng nhiều chủ đề).

Tuy nhiên, khi chạy ps ax -o pid,rss | grep <mypid> hoặc top, chỉ hiển thị 1,6 GB bộ nhớ cư trú RES/rss. Kiểm tra hoán đổi nói không sử dụng:

 
free -m 
      total  used  free  shared buffers  cached 
Mem:  129180  99348  29831   0  2689  73024 
-/+ buffers/cache:  23633  105546 
Swap:  15624   0  15624 

Tại sao JVM chỉ ra bộ nhớ 2.7GB được cam kết khi chỉ có 1,6 GB là cư trú? Phần còn lại đi đâu?

+0

có thể trùng lặp của [Có RSS theo dõi bộ nhớ được dành riêng hoặc cam kết không?] (Http://stackoverflow.com/questions/31071019/does-rss-tracks-reserved-or-commited-memory) – the8472

+0

không. rằng câu hỏi và câu trả lời thảo luận về bộ nhớ dành riêng nhưng không cam kết cũng như nói sự khác biệt giữa cam kết và cư trú là trao đổi, mà tôi đã chỉ ra không phải là trường hợp ở đây. –

+0

câu trả lời cũng bao gồm sự khác biệt giữa cam kết so với cư dân. – the8472

Trả lời

17

Tôi bắt đầu nghi ngờ rằng bộ nhớ ngăn xếp (không giống như heap JVM) dường như được tiền sử dụng mà không trở thành cư dân và theo thời gian trở thành đối tượng cư trú.

Có, malloc/mmap là lười trừ khi được nói cách khác. Các trang chỉ được hỗ trợ bởi bộ nhớ vật lý khi chúng được truy cập.

Bộ nhớ heap GC hiệu quả được chạm vào bởi bộ thu thập sao chép hoặc trước khi làm zero (-XX:+AlwaysPreTouch), do đó, nó sẽ luôn là đối tượng cư trú. Ngăn xếp chủ đề otoh không bị ảnh hưởng bởi điều này.

Để xác nhận thêm, bạn có thể sử dụng pmap -x <java pid> và tham chiếu chéo RSS của các dải địa chỉ khác nhau với đầu ra từ bản đồ bộ nhớ ảo từ NMT.


Bộ nhớ dành riêng đã được mmaped với PROT_NONE. Điều đó có nghĩa là khoảng không địa chỉ ảo có các mục trong cấu trúc vma của hạt nhân và do đó sẽ không được sử dụng bởi các cuộc gọi mmap/malloc khác. Nhưng chúng vẫn sẽ gây ra lỗi trang được chuyển tiếp đến tiến trình như SIGSEGV, tức là truy cập chúng là một lỗi.

Điều này rất quan trọng để có dải địa chỉ liền kề có sẵn để sử dụng trong tương lai, do đó đơn giản hóa số học con trỏ.

Bộ nhớ cam kết nhưng không được hỗ trợ đã được ánh xạ - ví dụ - PROT_READ | PROT_WRITE nhưng việc truy cập bộ nhớ vẫn gây ra lỗi trang. Nhưng lỗi trang đó được xử lý âm thầm bởi hạt nhân bằng cách sao lưu nó bằng bộ nhớ thực và quay lại thực thi như thể không có gì xảy ra.
I.e. đó là một chi tiết/tối ưu hóa triển khai sẽ không được chú ý bởi chính quá trình đó.


Để cung cấp một phân tích về các khái niệm:

Dùng Heap: dung lượng bộ nhớ bị chiếm đóng bởi các đối tượng sống theo GC cuối cùng

Cam: dãy Địa chỉ đã được ánh xạ với một cái gì đó khác với PROT_NONE.Họ có thể hoặc không thể được hỗ trợ bởi vật lý hoặc trao đổi do phân bổ và phân trang lười biếng.

Dành riêng: Tổng phạm vi địa chỉ đã được ánh xạ trước qua mmap cho một nhóm bộ nhớ cụ thể.
Các reserved - cam chênh lệch bao gồm PROT_NONE ánh xạ, được đảm bảo để không được hỗ trợ bởi bộ nhớ vật lý

trú: Các trang mà hiện đang trong ram vật lý. Điều này có nghĩa là mã, ngăn xếp, một phần của các vùng bộ nhớ cam kết mà còn là các phần của các tệp mmaped mà gần đây đã được truy cập và phân bổ ngoài sự kiểm soát của JVM.

Virtual: Tổng của tất cả ánh xạ địa chỉ ảo. Bao gồm cam kết, các vùng bộ nhớ dành riêng nhưng cũng được ánh xạ các tệp hoặc bộ nhớ dùng chung. Số này hiếm khi có thông tin vì JVM có thể đặt trước các dải địa chỉ rất lớn hoặc các tệp lớn mmap.

+0

Xác nhận qua pmap -x rằng phạm vi chuỗi được đưa ra bởi chi tiết kiểu chữ NMT có RSS chỉ 88 trong số 1028 hoặc hơn. Cảm ơn vì tiền hỗ trợ. Bạn có thể giải thích những gì cam kết thực sự có nghĩa là, và làm thế nào đó là khác nhau từ dành riêng nếu cả hai người trong số họ có thể tham khảo bộ nhớ ảo mà không phải là thực sự cư trú/sử dụng chưa? –

+0

cập nhật câu trả lời của tôi – the8472

+0

Cảm ơn! Rất hữu ích. Sẽ là tuyệt vời nếu theo dõi bộ nhớ riêng JVM thực sự kiểm tra dữ liệu mà pmap -x làm và cho thấy những gì đã thực sự cư trú là tốt. –

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