暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Java#Dump内存文件

小怂读书 2021-10-18
3921

这里不是记录如何通过Jhat、MAT分析内存文件,找出占用内存的大对象,去优化JVM参数。而是最近对内存分析过程中突然间发现(之前没有注意到的问题)dump下的文件大小7G,而通过MAT打开后发现对内对象一共不到100M,感觉很奇怪。


首先在服务器上通过jmap -heap <pid>命令,我查看当前Java程序的内存占用情况,因为项目运行过程发现设置的12G堆大小,竟然会使用超过10G,想找一下是哪些对象或者哪些操作导致的这样的内存占用情况。

通过jmap命令,我看到对大小12288M,已经使用5653M,于是我执行dump命令,生成x.hd堆内文件。当然Java程序运行过程中,堆内是不断变化的,有新对象的创建和老对象的销毁以及GC操作垃圾回收,而x.hd文件只是执行dump命令时的内存快照,并不在dump过程不断变化的。dump下的文件发现有7个G。


在使用MAT进行内存文件分析时,要确保MAT的运行内存大于dump文件,以便MAT有足够的空间进行文件的加载和分析,因此我找到MAT的配置文件,修改最大-Xmx最大值10240M。

在Mac下MAT的配置文件直接在应用程序中“查看包内容”,即可找到:

打开后修改对应的参数,保存即可。

-startup
../Eclipse/plugins/org.eclipse.equinox.launcher_1.6.200.v20210416-2027.jar
--launcher.library
../Eclipse/plugins/org.eclipse.equinox.launcher.cocoa.macosx.x86_64_1.2.200.v20210527-0259
-vmargs
-Xmx10240m
-Dorg.eclipse.swt.internal.carbon.smallFonts
-XstartOnFirstThread


然后在MAT中打开dump文件,发现问题,如下图。

发现堆内对象只有95M,这与7G相差很大,通过咨询大佬得知忽略了一个提示:

Unreachable Objects Histogram

不可达对象:这些通过垃圾回收算法遍历后没有GC Root的对象,就是不活跃的对象,可以作为下一次GC回收的对象,只是下一次GC还没有发生而存在内存中,被dump下来。

在执行jmap -dump:format=b,file=x.hd pid时没有指定live属性,这种情况下默认会将堆内所有的对象都输出出来,这就包括了不可达的对象。


MAT默认是不开启不可达对象的分析功能,因为包含不可达对象的分析时,MAT在加载dump文件,生成直方图,生成对象集合等过程都需要对大量不可达对象分析,严重占用内存;而且这些对象基本是中间变量,存活时间短,没有内存分析的必要。

如果要开启MAT的不可达对象分析,需要在Preference中设置:

勾选上面的属性后,重新打开x.hd文件。

而对于这些对象进行Merge GC Root操作时,发现它们没有被持有,即不可达。


文章转载自小怂读书,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论