[英]How does a JVM process allocate its memory?
我在理解JVM進程如何分配自己的內存方面有一點差距。 我所知道的
RSS = Heap size + MetaSpace + OffHeap size
其中OffHeap由線程堆棧,直接緩沖區,映射文件(庫和jar)和JVM代碼本身組成;
目前我正在嘗試分析我的Java應用程序(Spring Boot + Infinispan),其中RSS為779M (它在docker容器中運行,因此pid 1可以):
[ root@daf5a5ae9bb7:/data ]$ ps -o rss,vsz,sz 1
RSS VSZ SZ
798324 6242160 1560540
換句話說,我想解釋799M - (374M + 89M)= 316M的OffHeap內存。
每個線程消耗1M:
[ root@fac6d0dfbbb4:/data ]$ java -XX:+PrintFlagsFinal -version |grep ThreadStackSize
intx CompilerThreadStackSize = 0
intx ThreadStackSize = 1024
intx VMThreadStackSize = 1024
所以,在這里我們可以添加36M 。
應用程序使用DirectBuffer的唯一地方是NIO。 據我所知,從JMX可以看出,它不會消耗大量資源 - 只有98K
最后一步是映射libs和jar。 但是根據pmap
( 完整輸出 )
[ root@daf5a5ae9bb7:/data ]$ pmap -x 1 | grep ".so.*" | awk '{ sum+=$3} END {print sum}'
12896K
加
root@daf5a5ae9bb7:/data ]$ pmap -x 1 | grep “.jar" | awk '{ sum+=$3} END {print sum}'
9720K
我們這里只有20M 。
因此,我們仍然需要解釋316M - (36M + 20M)= 260M :(
有誰知道我錯過了什么?
做法:
您可能希望使用Java HotSpot本機內存跟蹤(NMT) 。
這可能會為您提供JVM分配的精確內存列表,分為不同區域堆,類,線程,代碼,GC,編譯器,內部,符號,內存跟蹤,池化空閑塊和未知 。
用法 :
您可以使用-XX:NativeMemoryTracking=summary
啟動應用程序。
可以使用jcmd <pid> VM.native_memory summary
對當前堆進行觀察。
在哪里可以找到jcmd / pid :
在Ubuntu上的默認OpedJDK安裝上,可以在/usr/bin/jcmd
。
通過運行不帶任何參數的jcmd
,您將獲得正在運行的Java應用程序的列表。
user@pc:~$ /usr/bin/jcmd
5169 Main <-- 5169 is the pid
輸出 :
然后,您將收到有關堆的完整概述,如下所示:
總計:保留= 664192KB,已提交= 253120KB <---本機內存跟蹤跟蹤的總內存
Java堆 (保留= 516096KB,已提交= 204800KB)<--- Java堆
(mmap:保留= 516096KB,已提交= 204800KB)
類 (保留= 6568KB,已提交= 4140KB)<---類元數據
(類#665)<---加載類的數量
(malloc = 424KB,#1000)<--- malloc'd memory,#malloc的數量
(mmap:保留= 6144KB,已提交= 3716KB)
線程 (保留= 6868KB,已提交= 6868KB)(線程#15)<---線程數
(stack:reserved = 6780KB,committed = 6780KB)<---線程堆棧使用的內存
(malloc = 27KB,#66)
(競技場= 61KB,#30)<---資源和處理區域
代碼 (保留= 102414KB,已提交= 6314KB)
(malloc = 2574KB,#74316)
(mmap:reserved = 99840KB,已提交= 3740KB)
GC (保留= 26154KB,已提交= 24938KB)
(malloc = 486KB,#110)
(mmap:保留= 25668KB,已提交= 24452KB)
編譯器 (保留= 106KB,已提交= 106KB)
(malloc = 7KB,#90)
(競技場= 99KB,#3)
內部 (保留= 586KB,已提交= 554KB)
(malloc = 554KB,#1677)
(mmap:保留= 32KB,已提交= 0KB)
符號 (保留= 906KB,已提交= 906KB)
(malloc = 514KB,#2736)
(競技場= 392KB,#1)
內存跟蹤 (保留= 3184KB,已提交= 3184KB)
(malloc = 3184KB,#300)
匯總免費大塊 (保留= 1276KB,承諾= 1276KB)
(malloc的= 1276KB)
未知 (保留= 33KB,已提交= 33KB)
(競技場= 33KB,#1)
這給出了JVM使用的不同內存區域的詳細概述,還顯示了保留和提交的內存。
我不知道一種技術可以為您提供更詳細的內存消耗列表。
進一步閱讀:
您還可以將-XX:NativeMemoryTracking=detail
與其他jcmd
命令結合使用。 可以在Java平台,標准版故障排除指南 - 2.6 jcmd實用程序中找到更詳細的說明。 您可以通過"jcmd <pid> help"
檢查可能的命令
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.