1.top
通过top命令,进入界面之后按P,根据CPU占用排序,找到最耗CPU的进行PID,从下图种可以发现PID为 15913。可以看到是java应用占用CPU。
2.top -p 15913 -H
加上 -H 选项可以该进程的相关线程信息,从下图种可知最耗CPU的两个线程PID分别是 15924和15925。
执行printf "%x\n" 15924
,得到对应的16进制为 0x3e34和0x3e35。
3.jstack堆栈跟踪
jstack 15913 > jstack.log
jstack命令可以得到线程堆栈信息,根据这些线程堆栈信息,可以去检查Java程序出现的问题,如检测死锁。
在日志的最后面找到了0x3e34和0x3e35,对应的是GC线程,由此猜想可能是不停的GC导致CPU占用过高。
也可以直接在终端搜索对应线程的上下文日志
jstack 15913 |grep -A 30 0x3e34
4.jstat虚拟机统计信息
jstat -gcutil 15193 1000 20
以上命令代码每过一秒打印一次gc情况,打印20次
S0:S0使用率;
S1:S1使用率;
E:Eden使用率;
O:老年代使用率;
P:PermGen的内存使用百分比;
M:MetaSpace的内存使用百分比;
YGC:Minor GC总共次数;
YGCT:Minor GC总共耗时,单位s;
FGC:Full GC总共次数;
FGCT:Full GC总共耗时,单位s;
由上图可知,20s内发生了13次Full GC,所以问题就是Full GC太频繁导致的,内存使用率太高,猜测可能是因为为JVM分配的内存太小了。
5.使用jmap查看内存情况
jmap -heap 15193
最大内存为948MB,老年代632MB,使用率已经无线接近100%。机器有4G内存,但为该进程分配的JVM最大内存只有948MB。
6.使用jmap -dump生成堆转储快照
jmap -dump:format=b,file==heap.hprof 15193
以上命令用于生成堆转储快照。可以使用jhat
进行快照分析。
7.可视化分析工具
Jconsole
:Java监视与管理控制台。可以实现内存监控,线程监控等。VisualVM
:多合一故障处理工具。可以用来显示虚拟机进程信息;应用程序的处理器,垃圾回收,堆,方法区以及线程信息;dump以及分析堆转储快照;方法级程序运行性能分析,找到调用最多,耗时最长的方法;离线程序快照等。Java Mission Control
:在线监控工具。