我遇到内存泄漏,这里有一些细节。
At the time of after-leak,
- top shows 50GB memory as residential
- heap dump file size is 25GB
- eclipse MAT analyzer tells me the heap size is 10GB
At the time of before-leak,
- top shows 30GB memory as residential
- heap dump file size is 20GB
- eclipse MAT analyzer tells me the heap size is 10GB
我很惊讶top,dump-dump大小和实际堆大小之间的差异。 我猜测顶部和堆之间的区别是垃圾收集器堆和本机堆区域的可能性。 但是,为什么堆转储文件大小和实际堆大小(来自eclipse MAT分析器)可能会有所不同?
对此问题的任何见解?
更新/答案
一些建议是使用jcmd(https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr007.html),因为该网站告诉“本机内存跟踪”。但是,如果您仔细阅读该页面,您将看到
Since NMT doesn't track memory allocations by non-JVM code,
you may have to use tools supported by the operating system
to detect memory leaks in native code.
因此,如果本机库中存在泄漏,则jcmd不是一个选项。
在对互联网进行数天爬行并尝试各种分析器之后,对此问题最有效的方法是使用 jemalloc 分析器。
这页帮助了我很多! https://gdstechnology.blog.gov.uk/2015/12/11/using-jemalloc-to-get-to-the-bottom-of-a-memory-leak/
答案 0 :(得分:3)
useFactory
和其他操作系统级工具显示您的JVM进程消耗了多少系统内存。由top
命令行选项定义的Java堆只是该内存的一部分。除了堆JVM需要一些内存。然后是java线程,每个线程都需要一定的内存。和Metaspace / Permanent Generation。还有其他几个。您可以阅读this blog post和this SO answer了解详情。
关于转储文件的大小和实际堆大小@ arnab-biswas的答案肯定是正确的。 MAT报告活动对象消耗的实际使用堆的大小。但堆转储包含整个堆,包括垃圾。
答案 1 :(得分:2)
我遇到过类似的情况。差异(HPROF文件大小 - MAT指示的堆的大小)实际上是垃圾(无法访问的对象)。无法到达的对象MAT中的直方图应该有帮助。
swap
只会转储活动对象而不是垃圾。
答案 2 :(得分:0)
要监控本机内存,您需要使用-XX:NativeMemoryTracking=summary
或-XX:NativeMemoryTracking=detail
启动应用程序。请注意,存在性能损失,因此在生产之前请三思而后行。
当内存跟踪处于活动状态时,您可以使用jcmd <pid> VM.native_memory summary
。还有其他命令可用,请检查https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr007.html或搜索本机内存跟踪。
答案 3 :(得分:0)
堆转储: 堆转储是特定时间点Java进程内存的快照。持久化此数据有不同的格式,并且根据格式可能包含不同的信息,但通常快照包含有关触发快照时堆中的Java对象和类的信息。通常在写入堆转储之前触发完整的GC,因此它包含有关剩余对象的信息。
有关 MAT 的信息,请参阅http://help.eclipse.org/neon/index.jsp?topic=/org.eclipse.mat.ui.help/welcome.html
答案 4 :(得分:0)
您要求从可靠/官方来源获取答案。让我试一试。
1)为什么我的JVM进程(由Top显示)占用的内存大于堆 大小
因为JVM进程的总内存消耗比Java堆更多。几个例子:
monitor-dashboard
可信/官方消息来源:Run-Time Data Areas和this blog post
2)为什么堆转储大小比MAT报告大得多?
因为MAT没有显示完整的堆。在索引创建期间,Memory Analyzer会删除无法访问的对象,因为各种垃圾收集器算法往往会留下一些垃圾。
可靠/官方消息来源:MemoryAnalyzer/FAQ