簡體   English   中英

JVM進程如何分配內存?

[英]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

根據jvisualvm ,承諾的堆大小為374M 在此輸入圖像描述

Metasapce大小為89M
在此輸入圖像描述

換句話說,我想解釋799M - (374M + 89M)= 316M的OffHeap內存。

我的應用程序(平均)有36個活動主題 在此輸入圖像描述

每個線程消耗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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM