標題采自:英雄聯盟-瑞文:斷劍重鑄之日,騎士歸來之時!
斷劍
前兩天早上在擠地鐵的時候看到小組群里,主管發了好多消息,打開來一看,說是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日志打印,本地線程監控,我想留到下一篇博客再介紹吧。謝謝
如果我不寫騎士歸來之時,強迫症是不是會很難受。那么就推薦一下,留個言,我大聲講出來。
