Java进程中已提交内存和RSS的区别

9

我正在运行一个简单的Java进程,运行Jetty,top显示2.9G的RAM。使用的JDK版本是1.8.0_112。

enter image description here

使用本地内存跟踪(jcmd),显示总承诺内存仅为1.5G内存。

enter image description here

此外,直接缓冲池的大小非常小,正如jvisualvm所报告的那样。

enter image description here

我完全知道NMT显示的内存是已提交的内存,不需要在RAM中。在这种情况下,NMT内存对RES的贡献应该小于1.5GB的RES内存。

在我的情况下,这里的差异约为1.4G(RES显示了1.4G的额外内存),不能仅归因于共享库、jar文件。有人能建议我如何知道这些额外内存是什么,哪些工具可以用来检查它们吗?

我已经检查了所有现有的相关问题在线/Stackoverflow,但没有找到任何合适的答案。

1个回答

4

pmap -X <pid> 命令将从操作系统的角度显示RSS的详细分解。

NMT 不会计算本地非JVM代码分配的内存,即使这些内存是通过标准的Java类库进行分配的,例如通过 ZipInputStream 的本地方法。详情请见相关问题

另一个可能的原因是 malloc 本身。本机内存分配器很少将未使用的内存返回给操作系统。例如,如果应用程序以小块方式使用 malloc 分配了1GB内存,然后释放了所有这些内存块,则从应用程序的角度来看,将有1GB的空闲内存,但操作系统很可能将此1GB计入RSS。该内存基本上属于应用程序的malloc池,并且可以重新用于将来的 malloc 调用。

尝试使用像 jemalloctcmalloc 这样的替代分配器。顺便说一下,它们都具有分配分析工具,可帮助查找本机内存泄漏。


我希望VM.native_memory,特别是Total.committed可以给我一个大致的基准,告诉我应该传递什么值给docker -m。就像楼主一样,我对于top -o %MEMTotal.committed之间存在如此大的差异感到非常困惑:( - Eugene

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接