问题
线上某一台机器出现异常.接口调用的rt达到了万级别..基本可以判断这个机器已经挂了.进而分析该机器一直在fgc.然后马上dump内存,进而进行分析(中间一些异常的gc日志没有截图).之前学习的jvm知识都是纯理论的,这次是实打实线上出现的问题.所以记录一下.
步骤
1 先dump对应的堆,然后从线上发到自己本机
dump的命令是
2 下载一个MAT工具
如果没有eclipse的话,还需要下载eclipse
mat的下载网址
http://www.eclipse.org/mat/downloads.php
找一个最合适自己的下载完..
3 调整eclipse的内存
具体的数值,需要看dump的文件大小.比如我的dump文件是1.3G,我就给了eclipse 2G的内存..据说有些dump文件有几十个G的大小,那么分析的机器也必须比这个大才行,否则eclipse本身就OOM了.
4 分析.
调整到 Memory Analysis 窗口,然后File->Open Heap Dump
然后选择dump的文件,然后MAT就自动会进行分析..分析完了,直接查看 Leak Suspects Report . MAT会自动帮你找内存泄露的疑凶.然后给你
点下面的Detail .可以看到最直观的类和所占用的大小
可以看到, IosPushClient 的直接引用是40byte 但是对应的间接引用达到了恐怖的420M 那么再点击该类,list obejcts .重点看间接引用占用的大的
接上图(截不下了.哈哈)
可以看到这个LinkedHashMap中,有47528个1776byte的对象.
其实看到这里,就基本清楚了.这个是由于在push的时候把对应的push消息给保留住,然后造成一直堆积在内存中造成的..
解决
在不修改对应的push底层实现的前提下,每次push了2W条消息就清理一次.后续有时间再修改底层逻辑吧.