为什么Java内存转储分析器中的堆总数与内存设置和总JVM使用量不对应?

时间:2014-01-23 15:41:40

标签: java memory jvm

我们使用Eclipse内存分析器进行Java(Tomcat Web应用程序)转储。生成的饼图中的总堆显示为86 Mb。同时,该JVM的堆限制设置为1.5GB,我们看到总JVM使用量高达2.8 GB。

偏差为何如此之大?

3 个答案:

答案 0 :(得分:2)

您的堆内存只是JVM使用的内存的一部分。此外,你有本机记忆和permgen。

您可以通过命令行参数限制permgen内存。见What does PermGen actually stand for?。根据我的经验,permgen限制默认为1G,这比我们需要的更多。我认为我们将它超越到128米。

本机内存非常棘手。这是由我的代码直接或传递使用的本机库分配的内存。

在jrockit中,您可以通过jrcmd print_memusage打印出内存摘要。不知道如何在其他JVM中执行此操作。

另外:http://www.ibm.com/developerworks/linux/library/j-nativememory-linux/index.html

答案 1 :(得分:2)

请调用jmap -heap TOMCAT_PID,您将看到当前的堆使用情况(伊甸园,幸存者空间,旧和烫发)

另请注意,Java的内存实际使用情况为 XMX + MaxPerm + XSS *线程编号。我建议你阅读关于Java中内存消耗的精彩帖子: http://plumbr.eu/blog/why-does-my-java-process-consume-more-memory-than-xmx

答案 2 :(得分:1)

请参阅此参考资料 - MAT Does Not Show the Complete Heap

  

症状:以交互方式监视内存使用情况时,使用的堆大小比MAT报告的大得多。

     

在索引创建期间,Memory Analyzer会删除无法访问的对象,因为各种垃圾收集器算法往往会留下一些垃圾(如果对象太小,移动并重新分配地址是昂贵的)。但是,这应该不超过3%到4%。如果您想知道删除了哪些对象,请按照此处的说明启用调试输出:MemoryAnalyzer/FAQ#Enable_Debug_Output

此外,此Q / A中应该有更多信息:eclipse memory analyzer sees small part (363,2MB) of entire heap dump (8GB)

尝试Keep Unreachable Objects中的Preferences -> Memory Analyzer -> Keep Unreachable Objects选项。