在这里总结一下查找Linux、Java环境下最耗CPU性能的代码段的方法。基本上原理就是使用top命令查看最耗cpu的进程和线程(子进程)。使用jstack把java线程堆栈给dump下来。然后,在堆栈信息中查找出对应的代码块。具体操作如下: 一、查找最耗cpu的进程执行:top 输出: PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 12789 root 20 0 3320m 689m 10m S 120.5 8.8 15430:42 java 31444 root 20 0 2694m 21m 6992 S 11.1 0.3 44:28.65 java 5031 root 20 0 2694m 21m 6992 S 6.9 0.3 264:18.50 java 2896 root 20 0 2004m 389m 15m S 1.4 4.9 0:47.65 java 3729 root 20 0 14936 1144 796 R 1.4 0.0 0:00.01 top 1 root 20 0 19248 1444 1156 S 0.0 0.0 0:02.50 init 2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kthreadd 3 root RT 0 0 0 0 S 0.0 0.0 0:00.02 migration/0 4 root 20 0 0 0 0 S 0.0 0.0 0:01.16 ksoftirqd/0 5 root RT 0 0 0 0 S 0.0 0.0 0:00.00 watchdog/0 这里我们看到最耗cpu的Java进程是:12789 二、jstack堆栈信息保存进入Java的安装目录(如:/usr/java/jdk1.6.0_34/bin),在bin文件夹中执行:./jstack 12789 > jstackResult.txt 这样,就将堆栈信息保存到jstackResult.txt这个文件中了。jstackResult.txt中的内容大体如下:
三、查出最耗cpu的子进程(java线程) 执行:top -p 12789 –H 输出: PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 11637 root 20 0 3320m 689m 10m S 13.7 8.8 573:57.24 java 9867 root 20 0 3320m 689m 10m R 2.7 8.8 216:57.68 java 29006 root 20 0 3320m 689m 10m S 2.7 8.8 3:49.73 java 28761 root 20 0 3320m 689m 10m S 2.3 8.8 3:55.86 java 29008 root 20 0 3320m 689m 10m S 2.3 8.8 3:50.22 java 29448 root 20 0 3320m 689m 10m R 2.3 8.8 3:37.94 java 30211 root 20 0 3320m 689m 10m R 2.3 8.8 3:17.72 java 30213 root 20 0 3320m 689m 10m R 2.3 8.8 3:18.59 java 1087 root 20 0 3320m 689m 10m S 2.3 8.8 2:00.05 java 13117 root 20 0 3320m 689m 10m S 2.0 8.8 574:07.45 java 13314 root 20 0 3320m 689m 10m S 2.0 8.8 574:12.15 java 13751 root 20 0 3320m 689m 10m S 2.0 8.8 564:11.94 java 14103 root 20 0 3320m 689m 10m R 2.0 8.8 560:00.50 java 14485 root 20 0 3320m 689m 10m R 2.0 8.8 559:24.82 java 16319 root 20 0 3320m 689m 10m R 2.0 8.8 551:27.09 java 17406 root 20 0 3320m 689m 10m R 2.0 8.8 549:19.02 java 17957 root 20 0 3320m 689m 10m R 2.0 8.8 547:40.06 java 找到12789下最耗性能的子进程。top命令使用-p参数来指定进程号,-H参数来显示线程。这里可以看到最耗cpu的进程(java中的线程)是11637。 四、从堆栈信息中查找最耗费性能的代码块从上面看到,我们用top找出来的pid是十进制的。而dump下来的nid是十六进制的。其实他们是一个东西,只是进制不同。利用printf命令格式化来转换一下进制。 执行:printf %0x 11673 输出:2d99 通过在dump出的堆栈信息中查找,就能找到问题所在了。
|