java進程占用系統內存高,排查解決


故障:今天許多開發反饋測試平台卡,訪問不了,第一感覺判斷是服務器內存爆了,或者cpu占用過高,上服務器看了一下,確實是內存爆了。然后開始定位問題原因,因為阿里這邊安全的原因,具體的圖片就不方便上傳了,拿網上的圖來說

 

  1. 使用top命令查看系統資源的使用情況,命令:top

     

    blob.png

     

     

    如圖可以看到java的進程內存使用率較高,java進程的內存使用率達到了70%+

     

 

2.定位線程問題(通過命令查看9718進程的線程情況),命令:ps p 9718 -L -o pcpu,pmem,pid,tid,time,tname,cmd

  blob.png

  

 由此可以看到這PID:9718的進程產生了很多線程。接下來就可以通過jstack查看內存使用的堆棧。

 

3. 查看內存使用的堆棧:在這里我們挑選了TID=9731的線程進行分析,首先需要將9731這個id轉換為16進制。需輸入如下命令,

 

 printf "%x\n" 9731

 

blob.png

 

 接下需要使用16進制的2603

 

4. 將PID為9718的堆棧信息打印到jstack.log中,命令:jstack -l 9718 > jstack.log

 

   blob.png

 

5. 查看堆棧信息文件,命令:vim jstack.log

 

   在進行搜索TID為2603的相關信息。如圖:

   

   blob.png

 

   可以看到這個線程狀態為:WAITING。通過查看文件分析 看到大量 Java Thread State。

   說明它在等待另一個條件的發生,來把自己喚醒,或者干脆它是調用了 sleep(N)。

   此時線程狀態大致為以下幾種:

   java.lang.Thread.State: WAITING (parking):一直等那個條件發生;

   java.lang.Thread.State: TIMED_WAITING (parking或sleeping):定時的,那個條件不到來,也將定時喚醒自己。

 

6.代碼優化:將文件發送給開發。優化下線程

 

 

 

這里還有一種排查思路

 

在定位到具體的PID后,可以到處進程快照,看看這個線程做了啥

jstack -l 9718 > ./9718.stack

  

再用grep查看下線程在文件里做了啥

cat 9718.stack |grep '2603' -C 8

  

這里隨便定位一個,基本上這樣查都可以定位到線程的問題

 


免責聲明!

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



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