39

我试图找到我的记忆在 linux 中运行的 java 进程的去向。有人建议我使用 pmap -x 来查看内存在做什么。

输出真的很长,但基本上它的很大一部分是重复这个:

00007fbf75f6a000    1016       -       -       - rwx--    [ anon ]
00007fbf76068000      12       -       -       - -----    [ anon ]

这到底是什么意思?为什么我有这么多(4000+)的条目?

4

4 回答 4

40

Anon 块是通过 malloc 或 mmap 分配的“大”块——参见手册页。因此,它们与 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 内存问题?

于 2009-09-27T12:15:13.873 回答
4

这部分 这部分是针对匿名内存的系统性能调优。

于 2009-09-25T15:34:35.750 回答
3

我以前在线程泄漏中看到过这种模式。如果你有代码试图池化线程,但不知何故弄乱了线程并泄漏了一个线程,你会在 pmap 中得到类似的模式。

我认为每一位内存都是线程的最小堆栈大小,当然在我们的例子中它与堆无关。
当我们达到操作系统限制时,我们仍然得到 OutOfMemoryErrors,即使当我们分析堆时它也没有过度分配。

当我们遇到这样的问题时,pmap [pid] | grep -c 12K原来是正在使用的线程数。

于 2011-07-30T00:15:09.910 回答
2

使用 Eclipse MAT(当您在 Java 堆而不是本机堆中获得 OutOfMemoryExceptions 时)。

于 2009-10-07T02:20:12.237 回答