JVM---jstack分析Java執行緒CPU佔用,執行緒死鎖的解決
本文章主要演示在Windows環境,Linux環境也差不多。
一、分析CPU佔用飆高
首先寫一個Java程式,並模擬一個死迴圈。讓CPU使用率飆高。CPU負載過大的話,新的請求就處理不了了,這就是很多程式變慢了甚至不能訪問的原因之一。
下面是我這裡的Controller,啟動程式之後,開多個請求訪問這個方法。死迴圈程式碼就不貼了,自己構造。我這裡模擬的一個擷取字串的死迴圈。
/** * 演示死迴圈導致cpu使用率飆高 * */ @RequestMapping("/loop") public List<Long> loop(){ return getPartneridsFromJson(); }
啟動程式,檢視執行緒id,我這裡是 796
開多個請求訪問Controller方法,可以在工作管理員看到CPU不斷增高。我開了7個視窗請求。Linux下可以通過 top命令檢視CPU佔用率。
現在發生了問題,開始定位問題。問題是我們手動構造的,實際生產環境肯定比這個複雜的多。
先把Java執行緒資訊輸出到指定檔案,我這裡就輸出到桌面的cpu.txt檔案中,如下
某執行緒部分屬性說明:
jstack 796 > cpu.txt
Windows下要藉助一個工具,檢視系統程序以及執行緒的詳細資訊:
ProcessExplorer :下載地址:ProcessExplorer
解壓,啟動,長這樣
熟悉的身影,PID為796的Java程序。CPU佔用率最高。
在java.exe上右鍵選擇Properties,在彈出的視窗選擇Thread資訊
可以看到7個CPU佔用異常高的執行緒。這裡的TID就是執行緒ID,不過是10進位制的。剛剛我們jstack匯出來的cpu.txt檔案中的執行緒id是16進位制的。
Linux下可以通過命令:
top -p 796 -H
檢視執行緒的CPU佔用率。
隨便看一個,13812轉換成16進製為:35f4,我們在cpu.txt搜一下這個執行緒
**可以發現,這個執行緒是執行中的狀態,在執行indexOf方法。是JVMTuningController.getPartneridsFromJson這個方法。**這樣就能定位到發生問題的位置了。實際生產情況要比這個複雜的多。就要慢慢分析了
二、分析執行緒死鎖
先構造一個死鎖方法,網上一搜一大把,我就不貼了。這是我的controller程式碼
/** * 演示死鎖 導致cpu使用率飆高 * */ @RequestMapping("/deadlock") public String deadlock(){ deadLock(); }
程式跑起來,然後請求這個方法。
輸出執行緒資訊到deadLock.txt
jstack 15808 > deadLock.txt
開啟deadLock.txt,看到最後面
以上這篇JVM---jstack分析Java執行緒CPU佔用,執行緒死鎖的解決就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。