一次線上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日志打印,本地線程監控,我想留到下一篇博客再介紹吧。謝謝

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


免責聲明!

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



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