我在理解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
(full output)
[ 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 :(
有没有人知道我错过了什么?
答案 0 :(得分:7)
<强>方法强>
您可能想要使用Java HotSpot Native Memory Tracking (NMT)。
这可能会为您提供JVM分配的精确内存列表,分为不同的区域堆,类,线程,代码,GC,编译器,内部,符号,内存跟踪,池化空闲块,< / em>和未知。
<强>用法强>:
您可以使用-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&lt; ---本地内存跟踪跟踪的总内存
Java堆(保留= 516096KB,已提交= 204800KB)&lt; --- Java堆
(mmap:reserved = 516096KB,已提交= 204800KB)
类(保留= 6568KB,已提交= 4140KB)&lt; ---类元数据
(类#665)&lt; ---已加载类的数量
(malloc = 424KB,#1000)&lt; --- malloc&#39;内存,#malloc的数量
(mmap:reserved = 6144KB,已提交= 3716KB)
主题(保留= 6868KB,已提交= 6868KB) (线程#15)&lt; ---线程数
(stack:reserved = 6780KB,committed = 6780KB)&lt; ---线程堆栈使用的内存
(malloc = 27KB,#66)
(竞技场= 61KB,#30)&lt; ---资源和处理区域
代码(保留= 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 Platform, Standard Edition Troubleshooting Guide - 2.6 The jcmd Utility找到。您可以通过"jcmd <pid> help"