在本教程中,我們創建了一個簡單的Java程序,使您可以逐步學習該技術。
故障排除工具
本教程將在下面使用以下工具:
- Windows Process Explorer (查明高CPU線程貢獻者)
- JVM線程轉儲(用于代碼級別的線程關聯和根本原因分析)
高CPU模擬器Java程序
下面的簡單程序只是循環并創建新的String對象。 這將使我們能夠按線程分析執行此CPU。 我建議您將其導入您選擇的IDE中,例如Eclipse并從那里運行它。 執行Windows計算機后,應立即觀察到CPU數量的增加。
package org.ph.javaee.tool.cpu;/*** HighCPUSimulator* @author Pierre-Hugues Charbonneau* http://javaeesupportpatterns.blogspot.com**/
public class HighCPUSimulator {private final static int NB_ITERATIONS = 500000000;// ~1 KB data footprintprivate final static String DATA_PREFIX = "datadatadatadatadatadatadatadatadatadatadatadatadatadatadatadata
datadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatad
atadatadatadatadatadatadatadatadatadatadatadatadatadatadatadata
datadatadatadatadatadatadatadatadatadatadatadatadatadatadatadata
datadatadatadatadatadatadatadatadatadatadatadatadatadatadatadata
datadatadatadatadatadatadatadatadatadatadatadatadatadatadatadata
datadatadatadatadatadatadatadatadatadatadatadatadatadatadatadata
datadatadatadatadatadatadata";/*** @param args*/public static void main(String[] args) {System.out.println("HIGH CPU Simulator 1.0");System.out.println("Author: Pierre-Hugues Charbonneau");System.out.println("http://javaeesupportpatterns.blogspot.com/");try {for (int i = 0; i < NB_ITERATIONS; i++) {// Perform some String manipulations to slowdown and expose looping process...String data = DATA_PREFIX + i; }} catch (Throwable any) {System.out.println("Unexpected Exception! " + any.getMessage()+ " [" + any + "]");}System.out.println("HighCPUSimulator done!");}}
步驟#1 –啟動流程瀏覽器
Process Explorer工具以可視方式動態顯示CPU使用情況。 這對于實時分析非常有用。 如果您需要每個線程在CPU上的歷史數據,則還可以將Windows perfmon與%Processor Time&Thread Id數據計數器一起使用。 您可以從下面的鏈接下載Process Explorer:
http://technet.microsoft.com/zh-cn/sysinternals/bb896653
在我們的示例中,您可以看到在執行示例程序之后,Eclipse javaw.exe進程現在使用了約25%的CPU利用率。

步驟#2 –啟動Process Explorer的Threads視圖
下一步是顯示javaw.exe進程的“線程”視圖。 只需右鍵單擊javaw.exe進程,然后選擇“屬性”。 將根據以下快照打開“線程”視圖:

- 第一列是線程ID(十進制格式)
- 第二列是每個線程使用的CPU利用率%–
- 第三列也是另一個計數器,指示線程是否正在CPU上運行
在我們的示例中,我們可以看到罪魁禍首是使用約25%CPU的線程ID#5996。
步驟#3 –生成JVM線程轉儲
此時,Process Explorer將不再有用。 目的是查明一個或多個Java線程,這些線程消耗了我們實現的大部分Java進程CPU利用率。 為了進入分析的下一個層次,您將需要捕獲JVM線程轉儲。 這將使您能夠將線程ID與線程堆棧跟蹤相關聯,從而可以查明這種處理類型正在消耗如此多的CPU。
JVM線程轉儲的生成可以通過幾種方式完成。 如果您使用的是JRockit VM,則可以按照以下示例使用jrcmd工具:

獲得線程轉儲數據后,只需搜索線程ID并找到您感興趣的線程堆棧跟蹤。
在我們的示例中,從Eclipse觸發的線程“主線程”被暴露為主要罪魁禍首,而這正是我們想要演示的。
Main Thread id=1 idx=0x4 tid=5996 prio=5 alive, native_blockedat org/ph/javaee/tool/cpu/HighCPUSimulator.main(HighCPUSimulator.java:31)at jrockit/vm/RNI.c2java(IIIII)V(Native Method)-- end of trace
步驟#4 –分析罪魁禍首的線程堆棧跟蹤并確定根本原因
此時,您應該具備進行根本原因分析所需的一切。 您將需要檢查每個線程堆棧跟蹤,并確定要處理的問題類型。 最后一步通常是您將花費大部分時間的地方,問題可能很簡單(例如無限循環),也可能很復雜(例如與垃圾回收相關的問題)。
在我們的示例中,線程轉儲確實揭示了CPU的高CPU數量來自第31行附近的示例Java程序。正如所料,它確實揭示了我們為本教程專門設計的循環條件。
for (int i = 0; i < NB_ITERATIONS; i++) {// Perform some String manipulations to slowdown and expose looping process...String data = DATA_PREFIX + i; }
我希望本教程可以幫助您了解如何分析和幫助查明Windows OS上Java CPU問題的根本原因。 請繼續關注更多更新,下一篇文章將為您提供Java CPU故障排除指南,包括如何處理最后的分析步驟以及常見問題模式。
參考: Java EE支持模式和Java教程博客中的JCG合作伙伴 Pierre-Hugues Charbonneau在Windows上的Java線程CPU分析 。
翻譯自: https://www.javacodegeeks.com/2012/04/java-thread-cpu-analysis-on-windows.html