1、問題
Tomcat服務器跑了一段時間後,發現Tomcat進程佔用的CPU資源在80%-100%間,加上其它的進程,整個服務器的CPU處理100%運行狀態。
2、通過process explorer查看Tomcat進程下的線程
process explorer下載:https://technet.microsoft.com/en-us/sysinternals/bb896653/
我使用的是漢化後的版本:http://download.csdn.net/detail/p_3er/9169985
下載後直接打開就可以了。
點開tomcat進程:
這時候發現6596、12200兩個TID線程佔用CPU最高。
下面我們要找到這兩個線程在我們程序中的位置。
3、通過jstack把進程下所以的Java線程棧的內容打印出文本中。
如我們的Tomcat進程PID爲900。
jstack -l 900 > 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後,問題得到解決。