Java内存高分析
首先要确定是不是堆内存使用高,可以用arthas或jmap等工具查看堆内存
如果堆内存不高,需要进一步查看是什么内存高:
修改启动脚本增加
-XX:NativeMemoryTracking=summary
执行命令打印统计
jcmd 4615 VM.native_memory
如果是thread的占用高,可以调整Xss参数,或者减少线程数
更多情况下是堆内存高,常见的分析办法:
-
统计内存中的对象,输入自己怀疑的对象,检查对象数是否正常
jmap -histo:live PID
这种方法一般是自己已经有怀疑的对象了,他不能提供调用堆栈 -
导出堆进行分析
使用jmap或arthas导出heap转储文件,然后用MAT工具,或者JMC工具进行分析,主要是找到占用多的对象 -
生成JFR文件进行分析,用jcmd命令来生成JFR,
jcmd 21393 VM.unlock_commercial_features
jcmd 21393 JFR.start name=test settings=profile delay=5s duration=2m filename="output.jfr"
或者用arthas命令:jfr start
JFR的原理是对cpu、内存等事件进行打点记录,记录后可以进行统计分析
JFR文件用jmc打开进行分析
网上很多工具都可以生成火焰图,推荐skj(又叫java瑞士军刀,https://github.com/rongfengliang/jfr-sjk-flame-graph-learning)
java -jar sjk.jar flame -f output.jfr -o jfr.html
JMC分析JFR文件,重点看几个地方:
在内存页面,按分配量排序,看分配最多的几个:
image.png
看他的分配堆栈,这样一般可以找到线索
image.png
这里可以看GC相关的数据:
image.png