Java堆转储和堆分析后的堆大小不同
我遇到内存泄漏,下面是一些细节 发生泄漏后Java堆转储和堆分析后的堆大小不同,java,eclipse,memory-leaks,jvm,heap-dump,Java,Eclipse,Memory Leaks,Jvm,Heap Dump,我遇到内存泄漏,下面是一些细节 发生泄漏后 顶部显示50GB内存作为住宅 堆转储文件大小为25GB EclipseMat analyzer告诉我堆大小是10GB 在发生泄漏之前 顶部显示30GB内存作为住宅 堆转储文件大小为20GB EclipseMat analyzer告诉我堆大小是10GB 我非常惊讶top、堆转储大小和实际堆大小之间的差异。 我猜top和heap之间的区别在于垃圾收集器堆和本机堆区域的可能性。 但是,堆转储文件大小和实际堆大小(来自EclipseMat analyz
- 顶部显示50GB内存作为住宅
- 堆转储文件大小为25GB
- EclipseMat analyzer告诉我堆大小是10GB
- 顶部显示30GB内存作为住宅
- 堆转储文件大小为20GB
- EclipseMat analyzer告诉我堆大小是10GB
我也经历过类似的情况。区别(HPROF文件大小—MAT指示的堆大小)实际上是垃圾(无法访问的对象)。MAT中的不可访问对象直方图在这里应该有所帮助
jmap-F-dump:live,format=b,file=
只转储live对象,而不转储垃圾。top
和其他操作系统级工具显示JVM进程消耗了多少系统内存。由-Xmx
命令行选项定义的Java堆只是该内存的一部分。除了堆,JVM本身还需要一些内存。然后是java线程,每个线程都需要一定数量的内存。和元空间/永久生成。还有其他几个。您可以阅读和了解更多信息
关于转储文件的大小和实际堆大小,@arnab biswas的答案肯定是正确的。MAT报告活动对象实际使用的堆的大小。但是堆转储包含整个堆,包括垃圾。为了监视本机内存,您需要使用
-XX:NativeMemoryTracking=summary
或-XX:NativeMemoryTracking=detail
启动应用程序。请注意,存在性能损失,因此在生产中进行此操作之前请三思
当内存跟踪处于活动状态时,您可以使用jcmd VM.native\u内存摘要
。还有其他可用的命令,请检查或搜索本机内存跟踪
编辑:在回答之前,我没有按照链接进行操作,您可能正在寻找类似的内容。堆转储: 堆转储是Java进程在某个时间点的内存快照。持久化此数据有不同的格式,根据格式的不同,它可能包含不同的信息,但通常快照包含有关触发快照时堆中java对象和类的信息。通常,在写入堆转储之前会触发完整GC,因此它包含关于剩余对象的信息
有关MAT的信息,请访问可靠/官方来源。让我试一试 1) 为什么我的JVM进程(顶部显示)消耗的内存大于堆 尺寸 因为JVM进程的总内存消耗不仅仅包括Java堆。举几个例子:
- 生成(JIT:ed)代码
- 加载的库(包括jar和类文件)
- java堆的控制结构
- 线程堆栈
- 用户本机内存(JNI中的malloc:ed)
可靠/官方消息来源:谢谢,我现在明白了。但我仍然需要知道住宅规模和堆规模之间的区别。请参阅其他有趣的链接,谢谢您的回答。看起来您建议使用NativeMemoryTracking,但这并不能真正跟踪本机库本身的内存分配。它只能根据此跟踪java代码分配。“由于NMT不跟踪非JVM代码的内存分配,您可能必须使用操作系统支持的工具来检测本机代码中的内存泄漏。”