mik*_*ail 12 java linux jvm memory-leaks spring-boot
我在理解JVM进程如何分配自己的内存方面有一点差距.我所知道的
RSS = Heap size + MetaSpace + OffHeap size
Run Code Online (Sandbox Code Playgroud)
其中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
Run Code Online (Sandbox Code Playgroud)
换句话说,我想解释799M - (374M + 89M)= 316M的OffHeap内存.
每个线程消耗1M:
[ root@fac6d0dfbbb4:/data ]$ java -XX:+PrintFlagsFinal -version |grep ThreadStackSize
intx CompilerThreadStackSize = 0
intx ThreadStackSize = 1024
intx VMThreadStackSize = 1024
Run Code Online (Sandbox Code Playgroud)
所以,在这里我们可以添加36M.
应用程序使用DirectBuffer的唯一地方是NIO.据我所知,从JMX可以看出,它不会消耗大量资源 - 只有98K

最后一步是映射libs和jar.但根据pmap(完整输出)
[ root@daf5a5ae9bb7:/data ]$ pmap -x 1 | grep ".so.*" | awk '{ sum+=$3} END {print sum}'
12896K
Run Code Online (Sandbox Code Playgroud)
加
root@daf5a5ae9bb7:/data ]$ pmap -x 1 | grep “.jar" | awk '{ sum+=$3} END {print sum}'
9720K
Run Code Online (Sandbox Code Playgroud)
我们这里只有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
Run Code Online (Sandbox Code Playgroud)
输出:
然后,您将收到有关堆的完整概述,如下所示:
总计: 保留= 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"
| 归档时间: |
|
| 查看次数: |
1840 次 |
| 最近记录: |