1.GC如果想查找到存活的對象癣诱,根據(jù)可達分析算法 根據(jù)GCRoot引用鏈遍歷存活對象。
根據(jù)GCRoot遍歷過程中护赊, 按照是否訪問過該對象 分為三種不同顏色曾沈。
白色:本對象沒有訪問過 (有可能是為垃圾對象)陷谱;
黑色:本對象已經(jīng)被訪問過烙博,且本對象的所有屬性都被訪問過;
灰色:本對象已經(jīng)被訪問過烟逊,且本對象的所有屬性沒有訪問過渣窜;本對象所有屬性都訪問過后,本對象有灰色變?yōu)楹谏?/p>
原理:
1.初始時宪躯,所有對象都在白色容器中乔宿;
2.當收集器在做初始標記的時候,會暫停所有的用戶線程访雪,標記GCRoot關聯(lián)的直接對象A和B详瑞;
放入到灰色盒子中。
3.在并發(fā)標記中(用戶線程與GC線程同時運行)臣缀,將本對象引用到其他對象移動灰色容器中坝橡,如果
該對象沒有引用到其他對象或者其他對象已經(jīng)標記過,則該對象放到黑色容器中精置。
4.重復以上這些操作计寇,到灰色容器為空時,則停止脂倦。
5.結(jié)束后番宁,如果在白色容器中任然存在的對象,則認為就是與GCRoot沒有直接關聯(lián)赖阻,則認為就是為不可達對象蝶押,
可以被垃圾回收線程清理。
三色標記算法:在并發(fā)標記中存在的問題火欧,因為用戶線程與GC線程同時運行棋电,有可能存在多標茎截、漏標記問題。
多標-浮動垃圾算法:
1.因為用戶線程與GC線程同時運行离陶,GC線程先執(zhí)行遍歷到C對象稼虎,C對象已經(jīng)存放到灰色容器中,突然用戶線程
修改了B.屬性C=Null招刨,這時候C已經(jīng)是為垃圾對象了,但是C對象已經(jīng)存放到灰色容器中哀军,繼續(xù)向下遍歷沉眶,GC線程
不認為是垃圾對象,這個過程我們可以稱作為浮動垃圾杉适,只能在下一次GC回收的時候清理谎倔。
2.并發(fā)清除時,用戶線程與GC線程同時運行猿推,用戶線程產(chǎn)生的浮動垃圾片习,只能在下一次清理。
漏標問題:
當遍歷的C對象的時候蹬叭,C對象已經(jīng)存放到灰色容器中藕咏,突然用戶線程修改C對象屬性.E=Null; E對象與C對象斷開,則E
對象為垃圾對象秽五,但是用戶線程修改B對象的屬性=E對象孽查,但是B對象已經(jīng)為黑色不會繼續(xù)遍歷,就會導致E對象會被垃圾線程
清理坦喘,這個過程稱作為漏標問題盲再。
D.屬性E=null;B.屬性E=E瓣铣;
漏標的問題滿足兩個條件:
1.至少有一個黑色對象指向了白色對象
2.所有灰色對象掃描完整個鏈時答朋,刪除之前所有白色對象。
漏標解決方案:
CMS收集器中處理漏標問題(增量更新):
滿足了第一個條件(灰色對象不在關聯(lián)白色對象的時候)棠笑,當黑色對象關聯(lián)該白色對象的時候會記錄該黑色對象梦碗,
在重新標記的時候,以該黑色對象變?yōu)榛疑溃瑥男麻_始修正標記叉弦,但是這種方案能夠確保垃圾都被清理,缺點就是效率非常低藻糖,
因為會掃描到整個黑色對象所有引用淹冰。
G1收集器中處理漏標問題(原始快照SATB):
滿足了第一個條件(灰色對象不在關聯(lián)白色對象的時候),記錄該白色對象變?yōu)榛疑奁猓谥匦聵擞浀臅r候掃描該白色對象整個引用鏈樱拴,但是如果黑色對象沒有引用該白色對象的時候柠衍,這時候就會產(chǎn)生浮動垃圾,只能在下一次清理晶乔。
相對于來說原始快照方式比增量更新方式容易產(chǎn)生浮動垃圾珍坊,但是效率比增量更新要高。
七種收集器總結(jié)
SerialGC 串行收集器 復制算法 新生代 響應速度快 適合單核的客戶端應用程序下正罢。
ParNew 并行收集器 復制算法 新生代 響應速度快 適合多核的cpu情況下 默認與cms配合使用
Parallel 并行收集器 復制算法 新生代 吞吐量優(yōu)先 適合于后端多核cpu情況下 堆內(nèi)存不是很大
SerialGCOld 串行收集器 標記整理算法 老年代響應速度快 適合單核的客戶端應用程序下阵漏。
Parallel old 并行收集器 標記整理算法 老年代 老年代吞吐量優(yōu)先 適合于后端多核cpu情況下 堆內(nèi)存不是很大
CMS 收集器并發(fā)收集器 標記清除 老年代 響應速度快 適合于企業(yè)級B/S項目
G1收集器 并發(fā)收集器 標記整理算法/復制算法 響應速度優(yōu)先 適合于大型服務器端