前几天在测试服务器上发现Java进程的CPU使用率暴高,为了分析解决该问题,把过程记录如下:
1. 先找到Java的进程号
Linux下:
用top命令查看所有进程,可以明显看到Java的,因为CPU占用率很高被排在前面。比如,
clip_image002
Windows下:
打开任务管理器,然后点击 “查看” 菜单,然后点击 “选择列”,把pid勾上,然后就可以在任务管理器里面看到所有进程的pid值了。(也可以用第三步中提到的工具直接查看)
- 做dump (可选)
jdk自带的jstack工具可以查看Java线程信息,可以实时查看,也可以导出来。如果发现实时查看不是很方便或者无法实时查看,在做下列步骤前可以先dump。
jstack -l > dump.stack
如果进程已经hang住了,加-F参数
jstack -l -F > dump.stack
当然,如果是Unix下,还有种方法:
kill -3
3. 找到里面是哪个线程占用率最高
Linux下:
用 top -H -p 查看该进程所有线程信息,找到占用率最高的那个
Windows下:
除了使用jvisualvm或者带上top-thread插件的jconsole之外,可以用Windows自己提供的三方工具—— Process Explorer v15.3
下载地址http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx
- 得到线程号的16进制
得到占用率最高的线程ID后,要把它转成16进制
Linux下:
printf “%x\n”
Windows下:
自带的计算器可以提供该功能
- 分析dump查找问题代码片
可以用 jstack | grep -A 来实时获取内存中该线程代码片,这里是第3步中得到的16进制的id
也可以在第2步中导出的dump里面查找第3步中得到的线程id的十六进制而找到代码片。
- 如果有UI,可以有更简单的办法
JDK自带工具jvisualvm和jconsole是非常强大的。其中jvisualvm原声支持实时查看线程CPU使用情况。
启动jvisualvm,并查看目标java进程信息,然后选择Sampler -> CPU -> Thread CPU Time
但是,这个sampler需要JMX支持,所以如果无法连接目标程序的JMX,就无法使用了。
jconsole并不能直接查看,但是在jdk1.6 中,demo目录下提供了一个top-thread的插件可以查看。1.7不知道为什么没了,可以猛击这里下载。
启动jconsole时,带上插件参数:
jconsole -pluginpath topthreads-1.1.jar
如果是脚本启动jconsole,比如JBOSS7自带的jconsole.sh的话,把该jar包加入其classpath可以OK。