1、問題
Tomcat服務器跑了一段時間后,發現Tomcat進程占用的CPU資源在80%-100%間,加上其它的進程,整個服務器的CPU處理100%運行狀態。
2、通過process explorer查看Tomcat進程下的線程
process explorer下載:https://technet.microsoft.com/en-us/sysinternals/bb896653/
我使用的是漢化后的版本:https://files.cnblogs.com/files/shuilangyizu/processExplorer漢化版.zip
下載后直接打開就可以了。
點開tomcat進程:
這時候發現6596、12200兩個TID線程占用CPU最高。
下面我們要找到這兩個線程在我們程序中的位置。
3、通過jstack把進程下所以的Java線程棧的內容打印出文本中。
如我們的Tomcat進程PID為900。
jstack -l 7388 > c:/java.stack
注:通過tomcat的windows服務啟動的tomcat是無法使用此命令獲取線程棧的內容(如下圖),必須通過startup.bat來啟動。
4、分析stack文本
打開c:/java.stack文件。
通過process explorer獲取到的線程TID對應的是stack文本線程棧描述內容中的nid的十進制值。
我們把TID為6596轉成十六進制為19c4,然后根據19c4在stack文本中找到此線程棧的描述內容為:
根據描述,我們可以看到,此線程是處理到了SocketThread類的91行處。
91行代碼是線程下的socket在阻塞狀態下等待讀取客戶端發送過來的數據。
后面幾個TID線程也是同樣的問題。
5、解決
經分析+谷哥+度娘后,socket服務器每與一個客戶連接都產生一條線程來處理事務的做法比較耗資源。
使用用NIO非阻塞的方式重寫了socket后,問題得到解決。