java垃圾回收目前采用的算法是可達性標記算法驯妄,即基于gc root進行可達性分析。分析標記過程采用三色標記法捡遍。
三色標記按照垃圾回收器 ”是否訪問過“ 為條件將對象標為三種顏色(邏輯概念)
白色:表示對象未被垃圾回收器訪問過碴卧;
灰色:表示對象本身被垃圾回收器訪問過攻旦,但這個對象上只少有一個引用未被訪問掃描過
黑色:對象完全被掃描,并且其所有引用都已完成掃描冕房。
其實灰色就是一個過渡狀態(tài)躏啰,在垃圾回收器標記完成結(jié)束后,對象只有白色或者黑色其中一種狀態(tài)耙册,當(dāng)為白色時给僵,說明該對象在可達性分析后沒有引用,也就是之后被銷毀的對象。當(dāng)為黑色時帝际,說明當(dāng)前對象為此次垃圾回收存活對象蔓同。
當(dāng)垃圾回收開始時,gcroot對象是黑色對象蹲诀。沿著他找到的對象A首先是灰色對象斑粱,當(dāng)對象A所有引用都掃描后,對象A為黑色對象脯爪,以此類推繼續(xù)往下掃描则北。
這是垃圾回收標記基本操作。
但目前的垃圾回收是并發(fā)操作的痕慢,就是在你進行標記的時候尚揣,程序線程也是繼續(xù)運行的,那原有的對象引用就有可能發(fā)生變化掖举。
比如已經(jīng)標記為黑色(存活對象)對象惑艇,程序運行將其所有引用取消,那么這個對象應(yīng)該是白色的(垃圾對象)拇泛。這種情況相對好一些滨巴,在下一次垃圾回收時候,我們還是可以把他回收俺叭,只是讓他多活了一會兒恭取,系統(tǒng)也不會出現(xiàn)什么問題,可以不解決熄守。
當(dāng)已經(jīng)標記為白色對象(垃圾對象)時蜈垮,此時程序運行又讓他和其他黑色(存活)對象產(chǎn)生引用,那么該對象最終也應(yīng)該是黑色(存活)對象裕照,如果此時垃圾回收器標記完回收后攒发,會出現(xiàn)對象丟失,這樣就引起程序問題晋南。
出現(xiàn)對象丟失的必要條件是(在垃圾回收器標記進行時出現(xiàn)的改變):
1.重新建立了一條或多條黑色對象到白色對象的新引用惠猿。
2.刪除了灰色對象到白色對象的直接或間接引用
因為已經(jīng)標記黑色的對象說明此輪垃圾回收中垃圾回收器對其的掃描已經(jīng)完成,不會再掃描负间,如果他又引用了一個白色對象偶妖,而且這個白色對象在垃圾掃描完后還是白色,那么這個白色對象最終會被誤回收政溃。
為了防止這種情況的出現(xiàn)趾访,上邊說的必要條件中的一個處理掉即可避免對象誤刪除;
當(dāng)黑色對象直接引用了一個白色對象后董虱,我們就將這個黑色對象記錄下來扼鞋,在掃描完成后,重新對這個黑色對象掃描,這個就是增量更新(Incremental Update)
當(dāng)刪除了灰色對象到白色對象的直接或間接引用后,就將這個灰色對象記錄下來云头,再以此灰色對象為根捐友,重新掃描一次。這個就是原始快照(Snapshot At TheBeginning盘寡,SATB)
自此,對象可達標記完成撮慨。