1.查看对象直方图(第一种方式)
jcmd [pid] GC.class_histogram > class_histogram.txt
通过【class_histogram】可以看到排名第一的【org.pentaho.di.core.metrics.MetricsSnapshot】创建了43290906个实例,是内存消耗最大的类,这个类是kettle中用户收集指标,并记录到ConcurrentLinkedQueue中,由此可以看出,由于日志量巨大,缓冲区可能已满,导致:
(1)快照对象MetricsSnapshot,和关联对象Date和Node无法被回收。
(2) 队列持续增长,最终沾满整个堆内存。
12411:
num #instances #bytes class name
----------------------------------------------
1: 43290906 1731636240 org.pentaho.di.core.metrics.MetricsSnapshot
2: 43300876 1039221024 java.util.Date
3: 43289667 1038952008 java.util.concurrent.ConcurrentLinkedQueue$Node
4: 425886 40336320 [C
5: 362099 11587168 java.util.concurrent.ConcurrentHashMap$Node
6: 425175 10204200 java.lang.String
7: 137616 6084656 [B
8: 56618 4982384 java.lang.reflect.Method
9: 21459 4893496 [I
10: 23127 4002928 [Ljava.util.concurrent.ConcurrentHashMap$Node;
11: 46059 3563320 [Ljava.lang.Object;
12: 23345 2602448 java.lang.Class
13: 44746 2147808 org.aspectj.weaver.reflect.ShadowMatchImpl
14: 79596 1910304 java.util.concurrent.ConcurrentLinkedQueue
15: 40916 1636640 java.util.LinkedHashMap$Entry
16: 49949 1598368 java.util.HashMap$Node
17: 17632 1525840 [Ljava.util.HashMap$Node;
......
2.分析堆转储(第二种方式)
执行以下命令,生成核心堆dump文件
jmap -dump:live,format=b,file=heapdump_[pid].hprof [pid]
如果内存较大建议使用以下命令分块生成(经测试不太行,有谁成功了可以回一下贴)
jmap -dump:live,format=b,file=heap.hprof,chunksize=1g [pid]
2.1将生成的dump文件(也就是xxx.hprof)导入到VisualVm中,也可以看到比对象直方图更多的内容。
2.2利用MAT工具进行分析。(第三种方式,比较推荐!)
执行以下命令生成堆dump文件
jmap -dump:live,format=b,file=heapdump_[pid].hprof [pid]
将dump文件导入到mat工具,可以较为直接的分析出内存占比,和问题对象,还有一些其他的关键信息!
注意:导入报错,或中间报错的情况,极有可能是dump过大,请调整MemoryAnalyzer.ini中的-Xmx参数,我的dump文件较大有11G,调整到-Xmx15g,才正常打开。
点击上图所指的Detail连接,可看到下图详细信息中,可以看到具体哪个对象占满的内存。
希望对您能有帮助!