我遇到内存泄漏,这里有一些详细信息。
发生后泄漏时,
- 顶部显示 50GB 内存为住宅内存
- 堆转储文件大小为 25GB
- eclipse MAT 分析器告诉我堆大小为 10GB
在泄漏之前,
- 顶部显示 30GB 内存为住宅内存
- 堆转储文件大小为 20GB
- eclipse MAT 分析器告诉我堆大小为 10GB
我对顶部、堆转储大小和实际堆大小之间的差异感到非常惊讶。 我猜测顶部和堆之间的区别是垃圾收集器堆和 native 堆区域的可能性。 但是,为什么堆转储文件大小和实际堆大小(来自 Eclipse MAT 分析器)可能不同?
对这个问题有什么见解吗?
更新/回答
一些建议是使用 jcmd ( https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr007.html ),因为网站告诉“ native 内存跟踪”。但是,如果你仔细阅读该页面,你会发现
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/
最佳答案
我也遇到过类似的情况。差异(HPROF 文件大小 - MAT 指示的堆大小)实际上是垃圾(无法访问的对象)。 MAT 中无法到达的对象直方图应该对此有所帮助。
jmap -F -dump:live,format=b,file=<file_name.hprof> <process_id>
只会转储 Activity 对象而不是垃圾。
关于Java堆转储和堆分析后的堆大小不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56651692/