第一步操作:
jmap -dump:format=b,file=/tmp/jmap_heapdump.hprof
生成DUMP日志-本地java中jvisualvm.exe查看分析
第二步操作:
jstack -l PID >/tmp/gc.log
第三步操作:
1.执行top -c命令,找到cpu最高的进程的id
2.执行top -H -p pid,这个命令就能显示刚刚找到的进程的所有线程的资源消耗情况。找到CPU负载高的线程tid 8627, 把这个数字转换成16进制,21B3(10进制转16进制,用linux命令: printf %x 172)。
3.执行jstack -l pid,拿到进程的线程dump文件。这个命令会打出这个进程的所有线程的运行堆栈。
4.用记事本打开这个文件,搜索“21B3”,就是搜一下16进制显示的线程id。搜到后,下面的堆栈就是这个线程打出来的。排查问题从这里深入。
第四步操作:
jstat -gccause PID 2000 50 --每2秒执行一次共执行50次
S0 S1 E O P YGC YGCT FGC FGCT GCT LGCC GCC
0.00 99.84 12.76 0.92 46.23 1 0.016 0 0.000 0.016 unknown GCCause No GC
######################## 术语分隔符 ########################
#S0 年轻代中第一个survivor(幸存区)已使用的占当前容量百分比
#S1 年轻代中第二个survivor(幸存区)已使用的占当前容量百分比
#E 年轻代中Eden(伊甸园)已使用的占当前容量百分比
#O old代已使用的占当前容量百分比
#P perm代已使用的占当前容量百分比
#YGC 从应用程序启动到采样时年轻代中gc次数
#FGC 从应用程序启动到采样时old代(全gc)gc次数
#FGCT 从应用程序启动到采样时old代(全gc)gc所用时间(s)
#GCT 从应用程序启动到采样时gc用的总时间(s)
#LGCC 最后一次GC的原因
#GCC 当前GC的原因
ps aux|grep java|grep -v grep|head -5|awk '{print $3,$1,$2}'|sort -rn #查询java进程前五的进程并进行排序
使用top命令定位异常进程。可以看见PID的CPU和内存占用率都非常高
此时可以再执行ps -ef | grep java,查看所有的java进程,在结果中找到进程号为12836的进程,即可查看是哪个应用占用的该进程。
使用top -H -p 进程号查看异常线程 得到NID
使用printf "%x\n" 线程号将异常线程号转化为16进制
使用jstack 进程号|grep 16进制异常线程号 -A90来定位异常代码的位置(最后的-A90是日志行数,也可以输出为文本文件或使用其他数字)。可以看到异常代码的位置。