首頁>技術>

程式碼介紹:

jdk提供的工具:

1、在Linux中啟動專案:java -cp ref-jvm.jar -XX:+PrintGC -Xms200M -Xmx200M ex13.FullGCProblem

2、top命令,實時顯示程序CPU百分比和記憶體使用情況:可以發現程序7498 佔用CPU比較高

等待一段時間:發現CPU使用率在逐漸增加

jinfo:顯示JVM引數設定資訊

jmap -heap 7498 :可以檢視記憶體使用情況

在不進行任何垃圾回收器指定情況的比例1:1:1

一段時間後 CPU佔比很高了

top -p 7498:單獨顯示7498程序佔比CPU

在監控介面輸入H,獲取當前程序下的所有執行緒資訊

jstack 7498:輸出執行緒資訊,nid為16進位制

將7500/7501換算成16進位制1D4C/1D4D,在介面中查詢,問題定位到CPU100%是瘋狂的垃圾回收的執行緒佔據的

jstat -gc 7498 2000 10:兩秒鐘重新整理一次GC資訊,一共查詢10次

各個欄位的含義如下:

不夠直觀,換個方式輸出:jstat -gc 7498 5000 20 | awk '{print $13,$14,$15,$16,$17}'

可以發現Full GC在增加,,說明記憶體不夠了

jmap -heap 7498,檢視堆記憶體情況,發現老年代使用率很大了,可能發生了記憶體洩漏

現在我們定位為是記憶體問題,CPU100%只是它的體現

jmap -histo 7498 | head -20:顯示堆空間對應7498程序對應物件佔用大小

問題總結(找到問題)

一般來說,前面那幾行,就可以看出,到底是哪些物件佔用了記憶體,這些物件回收不掉,導致了Full GC 裡面還有OOM

任務數多於執行緒數,那麼任務會進入阻塞佇列,就是一個佇列,因為程式碼中任務數一直多於執行緒數,所以每0.1s,就會有50個任務進入阻塞物件,50個任務底下有物件,至少物件送進去了,但是沒執行,所以導致物件一直都在,同時還回收不了。

為什麼回收不了,Executor是一個GCRoots,所以堆中,就會有60多萬個物件,阻塞佇列中60多萬個任務,futureTask,並且這些物件還回收不了。

總結

在JVM出現效能問題的時候(表現上是CPU100%,記憶體一直佔用)

1、出現CPU100%,要從兩個角度出發,一個有可能是業務執行緒瘋狂執行,比如說死迴圈,還有就是GC執行緒在瘋狂的回收,因為在JVM中垃圾回收器主流也是多執行緒的,所以很容易導致CPU100%;

2、在遇到記憶體溢位的問題的時候,一般情況下我們要檢視系統哪些物件佔用比較多,在實際業務程式碼中,找到對應的物件,分析對應的類,找到為啥這些物件不能回收的原因,就是透過可達性分析演算法,JVM的記憶體區域,還有就是垃圾回收器的基礎。

11
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • SSH遠端管理協議的工作原理