當前位置:編程學習大全網 - 源碼下載 - Jvm源GC

Jvm源GC

1.開始參數

2.回收原則

為了更好的了解GCDetails信息,回憶新壹代回收算法(圖片來自網友),這裏不再詳細解釋回收算法,也不介紹ParallelGC的參數,如XX:MaxGCPauseMilli,XX:GCTimeRatio。

3.GC詳細信息

分析

?並行清除是JDK8默認的新壹代垃圾收集算法,是以吞吐量為目標的垃圾收集器。基於標記復制算法,內存分配在堆內存中分為兩個區域,壹個用於新壹代,另壹個用於老壹代。默認情況下,新壹代占堆內存的1/3,老壹代占堆內存的2/3,新壹代分為Eden和Survivor_To。Survivor_From,默認分配比例為8:1:1。幸存者區負責存儲垃圾回收失敗的對象和升級到老年的操作。從上面的GCDetails可以分析出垃圾回收的壹般原理。

?以第壹種行為為例,131584K是回收前新壹代占用的內存大小,21503K是回收後新壹代占用的內存大小。可以知道,這次GC回收了大約110M,垃圾收集器使用的是並行清除。131584K是回收前整個堆內存占用的內存,42320K是GC後整個堆內存占用的內存。可以知道GC這次回收了89M左右的內存,垃圾收集器用的是並行Old,大概用了8.3ms,新壹代回收的內存和整個堆的內存之差就是新壹代升級到舊時代的內存大小,可以知道是265438+。

?以第二個GC為例,我們可以看到他觸發了全GC。原因很簡單,就是舊時代空間不足。在這個GC中,新壹代回收了16269K內存空間,OK表示新壹代所有內存都被回收了,老壹代回收了316390K-236940K內存空間,大約80M。整個堆內存已經回收了333077K-271355K內存空間,大概是61M。可以知道新生代記憶空間提升了80-61,大概是19M。

?在以往的生產經驗中,只要JVM或程序沒有相關告警,啟動參數很少調整。通過對GC日誌的研究和分析,我們發現堆內存的大小仍然直接關系到系統的吞吐量。您可以嘗試使用不同的-Xms和-Xmx1參數來測試系統的吞吐量。我們會發現,如果內存太小,年輕壹代GC就會頻繁發生,甚至頻繁發生滿GC或者內存泄漏。其實離譜的內存也會影響表現。在老年,STW(停止字)將需要很長時間,所以壹個合適的啟動參數是性能測試中必不可少的壹部分。

5.垃圾收集器的選擇參數

?當新壹代都是並行清除回收器的時候,我想用不同的老齡算法測試性能,準備用XX:+UseParallelGC和XX:+useparallelloldgc,但是發現老齡回收算法壹直是ParOldGen。經過壹段時間的迷茫,我發現JDK 7u4之後的7和JDK8的新壹代算法是並行掃取,老壹代算法默認是並行舊。

6.有點懷疑

?在上面的GC日誌中,有兩個括號,比如第壹行的(153088K)和(502784K),分別代表新生代分配的內存大小和堆內存分配的大小,但是我們發現這個大小並不是固定的,括號中的大小在GC之後發生了七次甚至更晚的變化。為什麽?實際上,JDK8並行清除默認開啟-XX:+ UseAdaptiveSizePolicy參數,它會根據吞吐量和垃圾收集時間動態調整每個內存區域的大小。雖然有新壹代SurvivorRatio=8的默認分配比例,但不會固定。如果在啟動參數顯示中寫了SurvivorRatio=8,則分配的內存不會動態調整,可以嘗試壹下。

?在JD8之前,除了並行清除,新壹代還有串行和ParNew垃圾回收。您可以通過以下指令來測試它們,所有這些指令都基於標記復制算法。GC日誌都是新壹代的相同分析方法。

1.開始參數

2.回收原則

?CMS作為老的垃圾收集期,以減少垃圾收集的暫停時間為目標,采用標簽移除算法,在新壹代垃圾收集中只能配合ParNew和Serial使用。JDK9以後只能配合ParNew使用。同樣,這部分也不詳細解釋原理,主要分析GCDetails日誌加深理解。這部分有兩個重要的概念,壹個是三色標簽法和讀寫障礙,另壹個是卡表結構。如果不知道,可以參考這篇文章。

3.GCDetails日誌

分析

?GC(分配失敗)是壹種垃圾收集算法,使用ParNew作為新壹代。這部分的內存情況和前面分析Parallel類似,所以這部分主要分析老CMS的垃圾收集原理。事實上,CMS垃圾收集日誌與垃圾收集的各個階段密切相關,主要是通過讀取日誌來強化垃圾收集的過程和原理。

1)初始標簽-CMS初始標記

?為了減少停頓時間,妳可以記住兩個標記階段是STW,其余階段是平行的。可以在日誌中了解到時間為0.328線時的壹些信息。在初始標記階段,陳年的已用內存大小為203782K,整個陳年的分配大小為349568K,整個堆內存的已用內存為221541k,整個堆內存分配的大小為506816K,標記時間也很短。由此可以粗略計算出新生代內存分配的大小約為506816k-349568k = 157m,與第壹行新生代內存分配的大小壹致。

2)並發標記-CMS-concurrent-mark,主要是基於初始標記來實現對象的可達性。需要0.01;為了知道在0.330時刻日誌中的平行標記;pre-clean-CMS-concurrent-preclean,主要解決並發標記過程中業務線程對對象引用關系的修改(包括跨代引用和引用變更),主要掃描標記為“臟塊”的卡表,耗時0.01s;;

3)預清洗-CMS-並發-可中止-預清洗可以終止。這壹步不壹定執行,如果新壹代的內存小於cmsschedule內存,也不會執行。如果大於這個值,就會有退出條件,比如周期數、時間閾值、Eden區內存利用率等。在這個周期退出之前,YGC將被引導去緩解後面最後壹個標記的壓力(因為在老年時代有壹個指向年輕壹代的指針)。從日誌中我們可以看到,YGC在0.331的可終止預清理階段進行了三次,從內存情況來看,大量的對象已經從新生代提升到了老年。

小疑惑:這部分我們的觀察時間指數是0.003/0.136秒,0.003s是CPU的執行時間,0.136s是終止預清理的總時間。兩者是有區別的。這部分我其實也沒有明確的答案。我的第壹感覺可能是在等新壹代GC。

3)最後標記-CMS最後備註

從日誌中0.468的時間可以分析出最終標記的結果,17759K是新壹代使用的內存大小,Rescan (parallel)是最後壹次標記SWT的時間,弱引用處理是清理弱引用的時間,類卸載是卸載未使用類的時間。擦洗符號表是清除符號表,我理解是清除符號引用,擦洗字符串表是清除字符表,我理解是清除字面量。最後,CMS最終標記後,陳年使用的內存為334051K,堆內存為351810K。

4)並發清理-CMS-並發-清掃,很好理解為並發清理;concurrent reset-CMS-concurrent-reset,重新調整CMS的內存結構,用於下壹次垃圾收集。

調諧

?在CMS中,非並發的垃圾收集會成功,也可能失敗,這將退化為串行的舊垃圾收集算法。為了避免這種情況,可以考慮CMS initiatingcoccupancyfraction參數,默認為92%。

  • 上一篇:瀏覽器老是顯示不了驗證碼怎麽辦?
  • 下一篇:人人都玩開心網的前 言
  • copyright 2024編程學習大全網