轉(zhuǎn)載
https://www.zhihu.com/question/53613423/answer/135743258
記錄R大的幾個觀點:
1. GC Roots
2. Tracing GC的思想
3. 分代的好處
4. Major GC和Full GC的區(qū)別
2. Tracing GC的思想
Tracing GC的根本思路就是: 給定一個集合的引用作為根出發(fā), 通過引用關(guān)系遍歷對象圖, 能被遍歷到的(可到達的)對象就被判定為存活, 其余對象(也就是沒有被遍歷到的)就自然被判定為死亡, 注意再注意: tracing GC的本質(zhì)是通過找出所有活對象來把其余空間認定為"無用", 而不是找出所有死掉的對象并回收它們占用的空間.
從root set出發(fā)遍歷看能順著引用遍歷到哪些young gen里的對象, 這些對象就被認定為是活的, 而young gen里剩余的空間, 無論是沒有對象還是有死對象, gc都不關(guān)系, 總之一股腦可以回收來用.
分代式GC對GC roots的定義的影響:
??分代式GC是一種部分收集(partial collection)的做法. 在執(zhí)行部分收集時, 從GC堆得非收集部分指向收集部分的引用, 也必須作為GC roots的一部分.
??具體到分兩代的分代式GC來說, 如果第0代叫做young gen,第1代叫做old gen, 那么如果有minor GC/young GC只收集young gen里的垃圾, 則young gen屬于"收集部分", 而old gen屬于"非收集部分", 那么從old gen指向young gen的引用就必須作為minor GC/young GC的GC roots的一部分.
??繼續(xù)具體到HotSpot VM里的分兩代GC來說, 除了old gen到y(tǒng)oung gen的引用之外, 有些帶有弱引用語義的結(jié)構(gòu), 例如說記錄所有當前被加載的類的SystemDictionary谬擦、記錄字符串常量引用的String Table等, 在young GC時必須要作為strong GC Roots, 而在收集整堆得full GC時則不會被看作strong GC roots.
劃重點:
結(jié)合上面的概念, 可以理解為young GC比full GC的GC Roots要更大一些.
3. 分代的好處
??對傳統(tǒng)的、基本的GC實現(xiàn)來說, 由于它們在GC的整個工作過程中都要"stop-the-world", 如果能想辦法縮短GC一次工作時間長度就是件重要的事情
, 如果說收集整個GC堆耗時太長, 那不如只收集其中的一部分.
??這個思路所基于的基本假設(shè): weak generational hypothesis
---大部分對象的生命期很短(die young), 而沒有die young的對象則很可能會存活很長時間(live long)
??這是對過往的很多應(yīng)用行為分析之后得出的一個假設(shè). 基于這個假設(shè), 如果讓新創(chuàng)建的對象都在young gen里創(chuàng)建, 然后頻繁收集young gen, 則大部分垃圾都能在young gc中被收集掉. 由于young gen的大小配置通常只占整個GC堆得較小部分, 而且較高的對象死亡率(或者說較低的對象存活率)讓它非常適合copying算法來收集, 這樣就不但能降低單詞GC的時間長度, 還可以提高GC的工作效率.
4. Major GC和Full GC的區(qū)別
4.1 針對HotSpot VM的實現(xiàn), 它里面的GC其實準備分類只有兩大種:
- Partial GC: 并不收集整個GC堆的模式
Young GC: 只收集young gen的GC
Old GC: 只收集old gen的GC, 只有CMS的concurrent collection是這個模式
Mixed GC: 收集整個young gen以及部分old gen的GC, 只有G1有這個模式 - Full GC: 收集整個堆, 包括young gen、old gen付魔、perm gen(如果存在的話)等所有部分的模式
Major GC通常是跟full GC是等價的, 收集整個GC堆. 當有人說"major GC"的時候一定要問清楚他想要指的是上面的Full GC還是old GC.