2022年11月15日 作者 zeroheart

JProfiler内存分析

1、简单的就是看那些存活的类,占用多好内存,然后可以选定一个对象,查看他的gcroot 路径,看能不能分析出来一些什么情况。

2、可以直接看分配,选聚合的引用,然后看是哪些类比较突出占用的多,在分析问题

比较抽象,具体问题具体分析。

参考的一个例子:(34条消息) java程序内存占用过高问题排查_JavaBlackHole的博客-CSDN博客_java内存占用高排查

一、现象

收到线上机器报警(内存使用过高),对报警的机器节点重启后恢复正常,搁天后新的节点又开始报警;

二、排查

直接对线上机器执行dump命令,由于线上机器还有流量在持续请求,因此dump时间比较长,生成的dump文件有16G+;因此我们先摘除了问题节点的流量,执行dump命令:

ps -ef|grep java 获取服务的pid

jmap -dump:live,format=b,file=/opt/mydump.hprof 3915 (只dump存活的日志)

生成的dump文件13G左右,压缩后还有3G,把mydump.hprof文件下载到本地

三、分析

用jprofiler工具进行分析,下面是分析步骤:

1.打开要分析的快照文件

2.点击最大对象

选择占用内存最大的对象,点击使用选定对象

选择传出引用,outgoing references 点击确认

3.点击reference引用查看

点击reference会显示刚才选定的最大对象的引用

展开查看详细信息,可以看到是由于线程池使用了无界队列(默认int的最大值)导致,队列中的任务有223589个,内存总占用7900MB

点击传入引用Incoming references,展开详细信息,展示更多,可以看到具体引用的类,InterflowProxy就是代码中用到线程池的类

至此,可以定位到具体占用内存过高的代码。