CPU高獲取其線程ID然后分析


一、具體步驟

shift+p 按照cpu排序
shift+m按照內存排序
1、查看進程下所有線程 top -H -p  pid 
2、將十進制數換成16進制:print "%x/n" 線程id
3、查看進程下的線程正在執行的方法:  jstack  pid|grep  0X70d4

 

以我們最近出現的一個實際故障為例,介紹怎么定位和解決這類問題。

clip_image002

clip_image002

 

根據top命令,發現PID為28555的Java進程占用CPU高達200%,出現故障。

通過ps aux | grep PID命令,可以進一步確定是tomcat進程出現了問題。但是,怎么定位到具體線程或者代碼呢?

首先顯示線程列表:

ps -mp pid -o THREAD,tid,time

找到了耗時最高的線程28802,占用CPU時間快兩個小時了!

其次將需要的線程ID轉換為16進制格式:

printf "%x\n" tid

2

2

 

最后打印線程的堆棧信息:

jstack pid |grep tid -A 30

3

3

 

找到出現問題的代碼了!

現在來分析下具體的代碼:ShortSocketIO.readBytes(ShortSocketIO.java:106)

ShortSocketIO是應用封裝的一個用短連接Socket通信的工具類。readBytes函數的代碼如下:

public byte[] readBytes(int length) throws IOException {

if ((this.socket == null) || (!this.socket.isConnected())) {

throw new IOException("++++ attempting to read from closed socket");

}

byte[] result = null;

ByteArrayOutputStream bos = new ByteArrayOutputStream();

if (this.recIndex >= length) {

bos.write(this.recBuf, 0, length);

byte[] newBuf = new byte[this.recBufSize];

if (this.recIndex > length) {

System.arraycopy(this.recBuf, length, newBuf, 0, this.recIndex - length);

}

this.recBuf = newBuf;

this.recIndex -= length;

} else {

int totalread = length;

if (this.recIndex > 0) {

totalread -= this.recIndex;

bos.write(this.recBuf, 0, this.recIndex);

this.recBuf = new byte[this.recBufSize];

this.recIndex = 0;

}

int readCount = 0;

while (totalread > 0) {

if ((readCount = this.in.read(this.recBuf)) > 0) {

if (totalread > readCount) {

bos.write(this.recBuf, 0, readCount);

this.recBuf = new byte[this.recBufSize];

this.recIndex = 0;

} else {

bos.write(this.recBuf, 0, totalread);

byte[] newBuf = new byte[this.recBufSize];

System.arraycopy(this.recBuf, totalread, newBuf, 0, readCount - totalread);

this.recBuf = newBuf;

this.recIndex = (readCount - totalread);

}

totalread -= readCount;

}

}

}

問題就出在標紅的代碼部分。如果this.in.read()返回的數據小於等於0時,循環就一直進行下去了。而這種情況在網絡擁塞的時候是可能發生的。

至於具體怎么修改就看業務邏輯應該怎么對待這種特殊情況了。

 

最后,總結下排查CPU故障的方法和技巧有哪些:

1、top命令:Linux命令。可以查看實時的CPU使用情況。也可以查看最近一段時間的CPU使用情況。

2、PS命令:Linux命令。強大的進程狀態監控命令。可以查看進程以及進程中線程的當前CPU使用情況。屬於當前狀態的采樣數據。

3、jstack:Java提供的命令。可以查看某個進程的當前線程棧運行情況。根據這個命令的輸出可以定位某個進程的所有線程的當前運行狀態、運行代碼,以及是否死鎖等等。

4、pstack:Linux命令。可以查看某個進程的當前線程棧運行情況。

 

 

 

Java 系統性能分析 命令

1. cpu分析 
top , pidstat(sysstat) 
pid -p PID -t 1 10 
vmstat 1 CPU上下文切換、運行隊列、利用率 
ps Hh -eo tid 
pcpu 查看具體線程的CPU消耗 
sar 來查看一定世界范圍內以及歷史的cpu消耗情況信息 

查看java線程信息 
jstack pid | grep 'nid=0x9999' 


2. cs sy消耗比較高 
上下文切換性能偏高, jstack -l pid, 查看on object monitor 

3. io消耗 
pidstat -d -t -p pid 1 100 
iostat 

4. 網絡io消耗 
cat /proc/interruptes 
sar -n FULL 1 2


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM