日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > java >内容正文

java

Java线上应用故障排查之一:高CPU占用

發(fā)布時(shí)間:2025/3/21 java 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java线上应用故障排查之一:高CPU占用 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一個(gè)應(yīng)用占用CPU很高,除了確實(shí)是計(jì)算密集型應(yīng)用之外,通常原因都是出現(xiàn)了死循環(huán)。

(友情提示:本博文章歡迎轉(zhuǎn)載,但請(qǐng)注明出處:hankchen,http://www.blogjava.net/hankchen

以我們最近出現(xiàn)的一個(gè)實(shí)際故障為例,介紹怎么定位和解決這類(lèi)問(wèn)題。

根據(jù)top命令,發(fā)現(xiàn)PID為28555的Java進(jìn)程占用CPU高達(dá)200%,出現(xiàn)故障。

通過(guò)ps aux | grep PID命令,可以進(jìn)一步確定是tomcat進(jìn)程出現(xiàn)了問(wèn)題。但是,怎么定位到具體線(xiàn)程或者代碼呢?

首先顯示線(xiàn)程列表:

ps -mp pid -o THREAD,tid,time

找到了耗時(shí)最高的線(xiàn)程28802,占用CPU時(shí)間快兩個(gè)小時(shí)了!

其次將需要的線(xiàn)程ID轉(zhuǎn)換為16進(jìn)制格式:

printf "%x\n" tid

最后打印線(xiàn)程的堆棧信息:

jstack pid |grep tid -A 30

找到出現(xiàn)問(wèn)題的代碼了!

現(xiàn)在來(lái)分析下具體的代碼:ShortSocketIO.readBytes(ShortSocketIO.java:106)

ShortSocketIO是應(yīng)用封裝的一個(gè)用短連接Socket通信的工具類(lèi)。readBytes函數(shù)的代碼如下:

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;

??????? }

?? }

}

問(wèn)題就出在標(biāo)紅的代碼部分。如果this.in.read()返回的數(shù)據(jù)小于等于0時(shí),循環(huán)就一直進(jìn)行下去了。而這種情況在網(wǎng)絡(luò)擁塞的時(shí)候是可能發(fā)生的。

至于具體怎么修改就看業(yè)務(wù)邏輯應(yīng)該怎么對(duì)待這種特殊情況了。

?

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

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

2、PS命令:Linux命令。強(qiáng)大的進(jìn)程狀態(tài)監(jiān)控命令。可以查看進(jìn)程以及進(jìn)程中線(xiàn)程的當(dāng)前CPU使用情況。屬于當(dāng)前狀態(tài)的采樣數(shù)據(jù)。

3、jstack:Java提供的命令。可以查看某個(gè)進(jìn)程的當(dāng)前線(xiàn)程棧運(yùn)行情況。根據(jù)這個(gè)命令的輸出可以定位某個(gè)進(jìn)程的所有線(xiàn)程的當(dāng)前運(yùn)行狀態(tài)、運(yùn)行代碼,以及是否死鎖等等。

4、pstack:Linux命令。可以查看某個(gè)進(jìn)程的當(dāng)前線(xiàn)程棧運(yùn)行情況。

?

(友情提示:本博文章歡迎轉(zhuǎn)載,但請(qǐng)注明出處:hankchen,http://www.blogjava.net/hankchen

《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專(zhuān)家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結(jié)

以上是生活随笔為你收集整理的Java线上应用故障排查之一:高CPU占用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。