一、排查步骤
1.1 top命令查看CPU占用情况
top
从图中可以看出进程id为9939的java应用占用CU284.1%
1.2定位CPU高的具体的进程主体
top -Hp 9939
1.3 将占用CPU高的线程pid转为16进制
printf "%x\n" 13953
1.4打印线程的堆栈信息
jstack 9939 |grep '3681' -A 100
或者
jstack 9939 > 9939.tdump
1.5查看GC信息(如果通过上一步分析出是GC task thread (ParallelGC)占用CPU高,那么可以通过如下命令查看GC信息)
jstat -gc 9939 5000
意思是每隔5秒打印进程ip为9939的应用GC信息
判断young gc是否不变,而fullgc一直在涨,如果符合这种情况,调整GC策略
-XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=5
UseConcMarkSweepGC表示这是并发收集器
UseCMSCompactAtFullCollection打开对年老代的压缩,可能会影响性能,但是可以消除碎片
CMSFullGCsBeforeCompaction由于并发收集器不对内存空间进行压缩、整理,所以运行一段时间以后会产生“碎片”,使得运行效率降低。此值设置运行多少次GC以后对内存空间进行压缩、整理
1.6内存快照
还可以使用jmap命令生成heap dump文件,以便更深入分析
jmap -dump:format=b,file=heapDump.hprof 9939
1.7使用MAT或者jdk自带的jvisualvm.exe进行分析
二、JVM启动参数
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./jvmdump
当发生OutOfMemoryError时自动生成文件名为jvmdump的 Heap Dump 文件到当前目录
-XX:+HeapDumpBeforeFullGC
当 JVM 执行 FullGC 前执行 dump
-XX:+HeapDumpAfterFullGC
当 JVM 执行 FullGC 后执行 dump
-Xloggc:./gc.log
jvm启动参数:在当前jar目录下输出GC日志,可通过gcviewer查看具体GC日志
三、参考文章
3、Java内存泄漏分析系列之五:常见的Thread Dump日志案例分析
8、OutOfMemoryError系列(2): GC overhead limit exceeded