一次線上FullGC問題記錄
標題採自:英雄聯盟-瑞文:斷劍重鑄之日,騎士歸來之時!
斷劍
前兩天早上在擠地鐵的時候看到小組群裡,主管發了好多訊息,開啟來一看,說是XX專案自從22號發版後,每天晚上就瘋狂Full GC,讓我們查一下什麼原因,嘻嘻嘻,一開始聽到,心裡竊喜,為什麼呢。因為自己以前對jvm也有些瞭解,不過都只是紙上談兵罷了。現在剛好有機會,到公司就和小夥伴開始排查。以下是full gc的圖片
圖 - 1.0
圖 - 2.0
圖 - 3.0
當然這是運維給出來的,一開始看到這個,我是懵逼的,這tm是什麼。接著往下看:運維又給出瞭如下圖的dump日誌
圖- 4.0
我心裡又問,這tm是什麼。哇,一臉懵逼的我,又去補了jvm的記憶體模型。
重鑄
就在我補給的時候,有個大佬已經發言了,
圖 -5.0
是不是感覺找到問題的來源了,就這有結束了,嘻嘻嘻。然後心裡一陣竊喜,還好是老程式碼。不是我寫的。但是事實卻沒有結束,為什麼了。接著往下看:
又一位大佬說:圖-6.0 應該就是這塊了
圖- 6.0
主管又說:雖然是老程式碼,但是以前沒發生過這樣的問題,但是自從22號發版後就開始了,她就查看了一下22號有關AssostantsDto 這塊有關的程式碼,並截圖發了出來
圖-7.0
看到發出來的這段,上面有我的署名 ouyangkang modify,我先是臉部發燙,然後大腦空白,接著回魂。我????? 寫的。emmmm............。有點印象,這段程式碼有問題?看下綠色的那段我改的程式碼,
首先獲取到一個list物件,遍歷該list,給list容器中的物件賦值,並重新把該物件新增list容器中,乍看一下,沒問題啊,這段程式碼。emm............................
仔細再看下綠色的那段我改的程式碼:
首先獲取到一個list物件,遍歷該list,給list容器中的物件賦值,並重新把該物件新增list容器中。等等,重新新增到list容器中,那麼該list容器的大小不就也更大嗎,那麼又會進行一次迴圈,這不發生了死迴圈嗎。哇!! 這就很有意思了,我的鍋,我的鍋。
那麼怎麼改呢:
第一種方案:直接去掉list.add(i,assistantsDto)。因為你堆list中的物件寫入內容的話,list中的物件引用的地址是不會改變的。
第二種方案:list.set(i,assistantsDto) 將改dto替換。
專案重新發版,果然這幾天xx專案再也沒有出現頻繁的Full GC了。
之日
圖-2.0 解釋
解釋斷劍中圖中含義:如果能夠看懂前面幾張圖的這節就可以跳過了。圖1.0就不解釋了,首先圖-2.0中第一行
60208.152(時間戳),[Full GC(Ergonomics)(解釋:發生了什麼GC)4035169K(解釋:jvm堆中記憶體已用大小)->3635904(解釋:經過full gc回收堆中記憶體後,堆中還剩餘的記憶體大小) (4178944K(解釋:jvm堆的總記憶體大小))]
從圖-1.0 中可以看出,經過一個full gc後,堆中可用記憶體還是不多,並且發生了很多次full gc。我們都知道full gc就是stop the word 連續的full gc 。那麼就導致這個專案不再對外提供服務了。
GC 策略
大概說一下GC有哪幾種回收策略,詳情網上都有,自行檢視,我就不寫了(偷懶),算了,我還是寫了點。
minor GC: 發生在年輕代。
一開始:當eden區物件寫滿的時候,發生minor GC,把存活物件放到S0,釋放其他物件所佔記憶體,繼續執行,eden區又寫滿了,發生minor GC,回收eden區和S0區存活物件,把存活物件防止S1,釋放其他物件所佔記憶體。eden區又寫滿了,發生minor GC,回收eden區和S1區存活物件,把存活物件防止S0,釋放其他物件所佔記憶體。反反覆覆,比較老一點的物件就放到了老年代。
major GC:發生在老年代:eg: 當發生minor GC 的時候,想把存活的老物件放到老年代,但是沒有這麼大的連續記憶體空間,此時就會發生major GC
full GC: 發生在年輕代和老年代 : eg: 當老年代和新生代記憶體都寫的快滿了的時候就會發生full GC|
JVM記憶體模型
大概說一下JVM記憶體模型:下次寫篇blog單獨介紹一下吧 。先欠著
圖-3.0 解釋
我擷取部分進行解釋:
S0C :Survivor0 可用記憶體大小 。 S1C: Survivor1可用記憶體大小
S0U:Survivor0 已用記憶體大小 S1U :Survivor1已用記憶體大小
EC: eden可用記憶體大小 EU:eden 已用記憶體大小
OC: 老年代可用記憶體大小 OU:老年代已用記憶體大小
MC:方法區可用記憶體大小 MU:方法區已用記憶體大小
CCSC :壓縮類空間記憶體大小 CCSU:壓縮類空間已用記憶體帶下
YGC: 年輕代垃圾回收次數 YGCT:young GC消耗的時間
FGC:full GC 回收次數 FGC:full GC 消耗的時間
GCT : GC 消耗的時間
圖-4.0 解釋
用mat工具開啟jump檔案所得到的,首先網上下載 mat,選擇適合你電腦系統的。至於怎麼操作,下次單獨拎出來介紹。
其實我還研究了一點jvm虛擬機器引數設定,GC日誌列印,本地執行緒監控,我想留到下一篇部落格再介紹吧。謝謝
如果我不寫騎士歸來之時,強迫症是不是會很難受。那麼就推薦一下,留個言,我大聲講出來。