我正在尝试定位在Linux上运行的Java进程的内存去向。有人建议我使用pmap -x来查看内存的具体情况。
输出结果非常长,但基本上其中很大一部分都是这样的重复:
00007fbf75f6a000 1016 - - - rwx-- [ anon ]
00007fbf76068000 12 - - - ----- [ anon ]
这到底是什么意思?为什么我会有这么多条目(4000+)?
我正在尝试定位在Linux上运行的Java进程的内存去向。有人建议我使用pmap -x来查看内存的具体情况。
输出结果非常长,但基本上其中很大一部分都是这样的重复:
00007fbf75f6a000 1016 - - - rwx-- [ anon ]
00007fbf76068000 12 - - - ----- [ anon ]
这到底是什么意思?为什么我会有这么多条目(4000+)?
匿名块是通过malloc或mmap分配的“大”块 - 请参阅man页面。因此,它们与Java堆没有任何关系(除了整个堆应该存储在这样的块中)。
根据我的经验,线程堆栈也使用匿名块。如果您看到许多具有相同大小的匿名块,并且该大小为512k到4Mb(下面的示例在我正在运行的Tomcat进程中重复了十几次),那么这可能是原因。根据程序的不同,您可能会有几十个这样的块;如果您看到成千上万个,则表示您存在线程问题。
b089f000 504K rwx-- [ anon ]
b091d000 12K ----- [ anon ]
b0920000 504K rwx-- [ anon ]
b099e000 12K ----- [ anon ]
b09a1000 504K rwx-- [ anon ]
b0a1f000 12K ----- [ anon ]
但这留下了一个问题:你为什么要使用pmap来诊断Java内存问题?
我在线程泄漏中曾经见过这种模式。如果您编写的代码试图池化线程,但某些方式弄错了并且泄漏了线程,那么您就会在pmap中看到这样的模式。
我认为每个内存位都是线程的最小堆栈大小,当然,在我们的情况下,它与堆没有任何关系。
即使我们分析了堆并未过度分配,当我们达到操作系统限制时仍然会出现OutOfMemoryErrors。
当我们遇到此类问题时,pmap [pid] | grep -c 12K
表明正在使用的线程数。