1.情景展示
java虛擬機占用這么高的CPU,肯定不正常!
2.原因分析
第一個是tomcat,正在運行java項目;
第二個是eclipse,因為eclipse的運行依賴於java。
現在的問題是:tomcat的CPU使用率達到了90%,單獨運行tomcat是不可能占用這么多CPU的,所以,問題就出現在:
java項目的CPU占有問題。
既然知道項目有問題,那就需要排查項目中具體哪個java類中的哪行代碼出了問題。
將第一個應用程序也就是tomcat關閉后,CPU立馬會降下來,這進一步證實了:是項目的問題。
3.解決方案
工具:Process Explorer
第一步:查看最占CPU程序所對應的pid
打開該應用,第二欄就是CPU,默認將程序按照CPU的占有率進行倒序排列,即:最占CPU的程序會排在最前面。
這個程序也就是tomcat,右側有個pid列,其對應的值是:12240
第二步:保存程序的線程信息
打開DOS命令窗口,在cmd命令窗口中執行命令:jstack 12240 > C:\Users\Marydon\Desktop\problem.log。
該命令的作用是將PID為12240的程序所包含的所有線程信息,保存在本地C:\Users\Marydon\Desktop\problem.log文件中。
第三步:查看占用CPU的線程
Process Explorer中,選中最占用CPU的那個應用(javaw.exe)--》右鍵Properties--》切換到Threads欄--》默認將線程按CPU進行倒序排列。
每行都代表一個線程,tid代表的就是該線程所對應的線程id(十進制)。
第四步:在線程文件中查找該線程id
根據該tid去log文件中查找,就能找到該線程所對應的java代碼。
由於,剛才導出的log文件中,存儲的線程id是16進制的,而我們在Process Explorer中看到的是10進制的tid,所以,我們需要將十進制轉換成16進制。
以tid=12352的線程為例,轉換成十六進制后為3040。
打開剛才的log文件,查找3040(0x3040)
意思是:WindowsSelectorImpl.java的第296行在使用該線程(也就是占內存的代碼所在)
去javaWeb項目中,打開WindowsSelectorImpl.java文件,跳到第296行,就是問題所在。
同樣的,對其它占用CPU高的線程也按這種方式進行排查即可。