1. 程式人生 > >一次線上FullGC問題記錄

一次線上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日誌列印,本地執行緒監控,我想留到下一篇部落格再介紹吧。謝謝

如果我不寫騎士歸來之時,強迫症是不是會很難受。那麼就推薦一下,留個言,我大聲講出來。