我们使用Eclipse内存分析器进行Java(Tomcat Web应用程序)转储。结果piechart中的总堆显示为86 Mb。同时,该JVM的堆限制设置为1.5GB,我们看到总JVM使用量高达2.8 GB。
为什么偏差这么大?
请调用jmap-heapTOMCAT_PID
,您将看到当前堆的使用情况(eden,幸存者空间,old和perm)
另外请注意,Java的实际内存使用量将是XMX MaxPermXSS*线程数。我建议你阅读关于Java内存消耗的精彩文章:http://plumbr.eu/blog/why-does-my-java-process-consume-more-memory-than-xmx
堆内存只是JVM使用的内存的一部分。此外,您还有本机内存和永久内存。
您可以通过命令行参数限制permgen内存。请参阅PermGen实际上代表什么?。根据我的经验,permgen限制默认为1G,这比我们需要的要多得多。我认为我们将其覆盖为128m。
本机内存要棘手得多。这是由代码直接或传递使用的本机库分配的内存。
在jrockit中,您可以通过jrcmdprint_memusage从内存摘要中打印出来。不知道如何在其他JVM中做到这一点。
还有:http://www.ibm.com/developerworks/linux/library/j-nativememory-linux/index.html
请参阅此参考-MAT不显示完整堆:
症状:交互监控内存使用情况时,使用的堆大小比MAT报告的要大得多。
在创建索引期间,内存分析器会删除无法访问的对象,因为各种垃圾收集器算法往往会留下一些垃圾(如果对象太小,移动和重新分配地址的成本太高)。但是,这应该不超过3%到4%。如果您想知道删除了哪些对象,请启用调试输出,如下所述:MemoryAnalyzer/FAQ#Enable_Debug_Output
此外,此Q/A中应该有更多信息:eclipse内存分析器可以看到整个堆转储(8GB)的一小部分(363,2MB)
尝试首选项中的
保持不可达对象
选项-