繼續接着上一次https://www.cnblogs.com/webor2006/p/11148282.html的理論學習,上一次學習到了這:
接着繼續:
SATB詳解:
- 對於三色算法在concurrent的時候可能產生的漏標記問題,SATB在marking階段中,對於從gray對象移除的目標引用對象標記為gray,對於black引用的新產生的對象標記為blcak;由於是在開始的時候進行snapshot,因而可能存在Floating Garbage。
- 漏標與誤標
誤標沒什么關系,頂多造成浮動垃圾,在下次gc還是可以回收的,但是漏標的后果是致命的,把本應該存活的對象給回收了,從而影響的程序的正確性。 - 漏標的情況只會發生在白色對象中,且滿足以下任意一個條件。
a、並發標記時,應用線程給一個黑色對象的引用類型字段賦值了該白色對象。
b、並發標記時,應用線程刪除所有灰色對象到該白色對象的引用。這是為何呢?舉個例子來說明這種漏標現象的發生:比如圖上所示,有三個gray對象里面有個成員變量都指向了一個白色對象,此時這三個gray里面的成員變量還木有被掃描到,接着應用線程刪除了所有灰色對象到該白色對象的引用,如下:
此時該white對象就成為了一個垃圾對象待回收了,目測現在這條件都是如預期,但是!!!假如在刪除之前有一個黑色對象也引用該白色對象了,如下:此時就會出現漏標的現象,本來該white對象不是垃圾反而當成垃圾被清理了。
- 對於第一種情況,利用post-write barrier,記錄所有新增的引用關系,然后根據這些引用關系為根重新掃描一遍。
- 對於第二種情況,利用pre-write barrier,將所有既將被刪除的引用關系的舊引用記錄下來,最后以這些舊引用為根重新掃描一遍。
停頓預測模型:
- G1收集器突出表現出來的一點是通過一個停頓預測模型根據用戶配置的停頓時間來選擇CSet的大小,從而達到用戶期待的應用程序暫停時間。
- 通過-XX:MaxGCPauseMillis參數來設置。這一點有點類似於ParallelScavenge收集器。關於停頓時間的設置並不是越短越好。
- 設置的時間越短意味着每次收集的CSet越小【設置的停頓時間越小則收集的垃圾越少,而收集的垃圾越少則意味着收集的region個數越少,而收集的region個數越少意味着由這些被收集的region所構成的CSet就越小】,導致垃圾逐步積累變多,最終不得不退化成Serial GC;停頓時間設置的過長,那么會導致每次都會產生長時間的停頓,影響了程序對外的響應時間。
G1的收集模式:
- Young GC:收集年輕代里的Region。
- Mixed GC:年輕代的所有Region + 全局並發標記階段選出的收益高的Region。
- 無論是Young GC還是Mixed GC都只是並發拷貝的階段。
- 分代G1模式下選擇CSet有兩種子模式,分別對應Young GC和Mixed GC:
Young GC:CSet就是所有年輕代里面的Region。
Mixed GC:CSet是所有年輕代里的Region加上在全局並發標記階段標記出來的收益高的Region。 - G1的運行過程是這樣的:會在Young GC和Mixed GC之間不斷地切換運行,同時定期地做全局並發標記,在實在趕不上對象創建速度的情況下使用Full GC(Serial GC,也就是從G1會回收到備選的方案,一定要盡量避免此情況出現)。
- 初始標記是在Young GC上執行的,在進行全局並發標記的時候不會做Mixed GC,在做Mixed GC的時候也不會啟動初始標記階段。
- 當Mixed GC趕不上對象產生的速度的時候就退化成Full GC,這一點是需要重點調優的地方。
G1最佳實踐:
- 不斷調優暫停時間指標
通過-XX:MaxGCPauseMillis=x可以設置啟動應用程序暫停的時間,G1在運行的時候會根據這個參數選擇CSet來滿足響應時間的設置。一般情況下這個值設置到100ms或者200ms都是可以的(不同情況下會不一樣),但是如果設置成50ms就不太合理。暫停時間設置的太短,就會導致出現G1跟不上垃圾產生的速度。最終退化成Full GC。所以對這個參數的調優是一個持續的過程,逐步調整到最佳狀態。 - 不要設置新生代和老年代的大小
1、G1收集器在運行的時候會調整新生代和老年代的大小。通過改變代的大小來調整對象晉升的速度以及晉升年齡,從而達到我們為收集器設置的暫停時間目標。
2、設置了新生代大小相當於放棄了G1為我們做的自動調優。我們需要做的只是設置整個堆內存的大小,剩下的交給G1自已去分配各個代的大小既可。 - 關注Evacuation Failure
Evacuation Failure類似於CMS里面的晉升失敗,堆空間的垃圾太多導致無法完成Region之間的拷貝,於是不得不退化成Full GC來做一次全局范圍內的垃圾收集。