在一个项目进行过程中,CPU使用率一直保持在接近100%的状态。通过了解资料和总结,得出以下结论:

  1. top

通过top命令,我们找到了消耗CPU最高的PID。从下面的图表中可以看出,PID为15913

  1. top -p 15913 -H

通过-H选项可以查看进程的相关线程信息。从下图中可以得知,最耗CPU的两个PID分别是15924和15925,对应的16进制分别为0x3E34和0x3E35

  1. jstack 15913 > jstack.log

jstack命令可以得到线程堆栈信息,根据这些线程堆栈信息,可以去查看java程序出现的问题,如检测死。jstack.log的完整内容在文章最后发出来。

在日志的最后面找到0x3e34 和 0x3e35,对应的是GC线程,由此猜想可能是不停地GC导致CPU占用过高。

需要注意的是,在单核机器上,根本看不到GC线程,这个16进制数指向的是JVM Thread,试了好几次都是这样,一开始在这上面浪费太多时间了。

jstack 15913 | grep -A 10 0x3e34

  1. jstat -gcutil 15193 1000 20

以上命令代码每过一秒打印一次gc情况,打印20次。

参数项说明如下:

由上图可知,20s内发生了13次Full GC,所以问题就是Full Gc 太频繁导致的,内存使用率太高,猜测可能是因为jvm分配的内存太小了。

  1. jmap -heap 15193

以上命令用于查看java进程的JVM内存情况

最大内存为948M,老年代632M,使用率已经无线接近100%。机器有4G内存,但为该进程分配的JVM最大内存只有948M.

  1. jmap -dump:format=b,file==heap.hprof 15193

以上命令用于导出jvm内存信息,这个我暂时也没看出什么。

  1. 增大堆内存

-Xms2048m -Xmx2048m ,增大堆内存到2048M,重启查看效果。

说明:系统启动之后3s内,CPU占用还是100%,接下来就降下来了。 通过jstat查看GC情况,发生了16次YGC,发生了12次 FGC,难道是系统启动的时候,创建了大量的对象?

不过接下来系统运行平稳,先观察一段时间看看。