在這裡總結一下查詢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出的堆疊資訊中查詢,就能找到問題所在了。