自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

掌握JVM中垃圾回收的三色標記算法

開發(fā) 前端
三色標記算法會產(chǎn)生多標和漏標問題,其中漏標問題最嚴重。漏標問題會導致本該存活的對象被回收,從而導致嚴重的程序問題。 CMS垃圾回收器采用了增量更新方式解決漏標問題,G1垃圾回收器采用了原始快照方式解決漏標問題。

    JVM在進行垃圾回收時候,首先需要確定哪些對象是需要回收的,哪些對象是不需要回收的,確認一個對象是否可以收回有以下的方案:

1.計數(shù)法

    每個對象都有一個計數(shù)器,被引用了加一,移除引用減一。計數(shù)法實現(xiàn)簡單,判斷高效,但是無法解決對象之間相互循環(huán)引用的問題,這個是此算法的邏輯漏洞,因此它并不被廣泛使用。

2.可達性分析法(引用鏈法)

    以GCRoots為基礎去掃描整個引用鏈,從而找到所有的可達對象,那剩下的其他對象就是不可達的垃圾對象了,如下所示:

圖片圖片

可達性分析法是現(xiàn)在被廣泛使用的判斷對象是否存活的算法。

1.為什么要使用三色標記算法

    可達性分析法的一種實現(xiàn)方案是從GCRoots節(jié)點開始,使用標記-清除算法來實現(xiàn)。這種實現(xiàn)方案有兩個階段,分別是:標記階段、清除階段。

    在標記階段,從GCRoots節(jié)點開始掃描整個引用鏈,找到所有可達的對象,如下圖所示的標記可達對象:

圖片圖片

    在清除階段中掃描整個引用鏈的不可達對象,然后將不可達的垃圾對象清除掉。這種實現(xiàn)方案有一個很大的缺點,那就是整個過程必須STW。CMS回收器出現(xiàn)之前的所有回收器,都是用這種方式實現(xiàn)的,因此GC停頓時間都比較長。

    為了解決標記-清除算法中的問題,于是就產(chǎn)生了三色標記算法,目前JVM中的CMS與G1垃圾回收器所使用垃圾回收算法即為三色標記法。

2.三色標記算法的工作原理

    三色標記算法是一種用于垃圾回收的標記算法,主要用于標記-清除類型的垃圾回收器。它通過將對象分為三種顏色(白色、灰色、黑色)來表示對象的狀態(tài),并通過顏色轉換來判斷哪些對象是可回收的。如下是幾種顏色的含義:

    白色:表示對象未被標記,默認情況下所有對象都是白色的。白色對象是垃圾回收的目標。

    灰色:表示對象被標記過,但它的引用尚未被檢查。即該對象是存活的,但它引用的對象可能仍未被標記。

    黑色:表示對象已經(jīng)被標記并且它引用的所有對象也都已經(jīng)標記過。即該對象以及它引用的對象都被認為是存活的。

    三色標記算法的執(zhí)行步驟如下所示:

(1)首先創(chuàng)建三個集合(白、灰、黑),初始的時候將所有對象放入白色集合中。

圖片圖片

(2)從根節(jié)點開始遍歷所有對象,把可達的對象從白色集合放入灰色集合,如下圖所示:

圖片圖片

(3)遍歷灰色集合,將灰色對象引用的可達的對象從白色集合放入灰色集合,之后將此灰色對象放入黑色集合,如下圖所示:

圖片圖片

(3)重復 3這個步驟,直到灰色中無任何對象,最后剩余的所有白色對象即為無用的對象,如下圖所示的最終標記結果:

圖片圖片

    三色標記算法通過將對象分為白色、灰色和黑色三個階段,利用標記和清理機制來判斷哪些對象是垃圾并進行回收。

3.三色標記算法的問題

    以CMS垃圾收集器中使用的是三色標記算法,現(xiàn)在以CMS執(zhí)行過程為例,如下是CMS工作圖:

圖片圖片

    CMS存在并發(fā)標記過程,當與用戶線程一起執(zhí)行的情況下標記時,由于用戶線程可能會隨時修改對象的引用狀態(tài),這就導致三色標記出現(xiàn)多標和漏標的問題。

(1)漏標的問題的產(chǎn)生

圖片圖片

    在t1時刻,C對象被標記成灰色并且C下存在一個白色對象D;在t2時刻C不在持有D對象,但是B持有D對象,此時B由于是黑色的,那么D就不會在被標記;t3時刻由于D是白色的,那么垃圾收集就會將D清理掉。這就產(chǎn)生了漏標的問題。

(2)多標問題的產(chǎn)生

圖片圖片

    在t1時刻A持有灰色對象C,在t2時刻A不再持有C對象,此時雖然C對象不可達,但是C對象被標記成灰色,那么就產(chǎn)生了多標問題。

4.三色標記算法中問題的解決方案

漏標問題要發(fā)生需要滿足如下兩個充要條件:

(1)有至少一個黑色對象在自己被標記之后指向了這個白色對象,如下圖中的B對象:

圖片圖片

(2)所有的灰色對象在自己引用掃描完成之前刪除了對白色對象的引用,如下所示的C對象:

圖片圖片

    只有當上面兩個條件都滿足,三色標記算法才會發(fā)生漏標的問題。那么如果我們破壞任何一個條件,這個白色對象就不會被漏標。

    CMS和G1垃圾回收器,它們都在并發(fā)標記階段之后新增了一個重新標記階段來校正并發(fā)標記階段中未被正確標記的對象,CMS垃圾回收器使用的增量更新方案來解決漏標的問題,G1垃圾收集器采用的是原始快照方案來解決漏標的問題。

    無論是增量更新還是原始快照都會借助寫屏障來協(xié)助標記,寫屏障可以理解成Spring中的AOP,寫屏障可以分為寫前屏障和寫后屏障。

4.1 CMS解決漏標的方案

    CMS回收器采用的是增量更新方案解決漏標問題,其打破的第一個條件,即有至少一個黑色對象在自己被標記之后指向了這個白色對象。

    增量更新使用寫后屏障,某個對象新增的引用時,將該對象記錄下來,掃描完后將這個對象變?yōu)榛疑珜ο笾匦聮呙?,在后續(xù)這個重新掃描的階段需要用戶線程STW,如下圖所示:

圖片圖片

    這種方式的缺點是會重新掃描新增的這部分對象,會浪費多一些時間。但是這段時間相對于并發(fā)標記整個鏈路的掃描來講還是可以接受的。

4.2 G1解決漏標的方案

    G1垃圾回收器采用的是原始快照的方案解決漏標問題,即破壞了“所有的灰色對象在自己引用掃描完成之前刪除了對白色對象的引用”的條件。

    原始快照使用寫前屏障,在刪除引用前保存要刪除的引用,在掃描完畢后將這些刪除的引用變?yōu)榛疑珜ο笾匦聮呙?,并且GC開始后發(fā)生新增引用時,使用TAMS(Top at Mark Start)指針對新增引用進行記錄。如下圖所示的過程:

圖片圖片

    E對象目前引用了F對象,C對象已標記完成,在下一個時刻的時候,E對象刪除了對F對象的引用,D對象添加了對C對象的引用

圖片圖片

    此時通過寫前屏障將C對象置為灰色,F(xiàn)對象標記成灰色,但是F其實是浮動垃圾,等到一下時刻,從灰色隊列中拉取對象重新標記,最后的結果如下所示:

圖片圖片

    原始快照的缺點是會產(chǎn)生浮動垃圾,因為當取消對象引用的時候,有可能是真的取消引用,對象是要回收掉的。但是通過這種方式,就會把本該回收的對象又復活了,從而導致出現(xiàn)浮動垃圾。總體來講,原始快照方式是可以接受的,因為在下次GC的時候垃圾還是會被回收的。

4.3、三色標記中多標的問題

    在并發(fā)標記階段,有可能之前已經(jīng)被標記為存活的對象,其引用被刪除,從而變成了不可達對象。

    多標問題會導致內(nèi)存產(chǎn)生浮動垃圾,但是其可以在下次GC的時候被回收,因此問題還不算很嚴重。

總結:

(1)三色標記算法是根可達算法的一種實現(xiàn)方案,其目的是為了找出所有可達對象。

(2)由于標記-清除算法效率太低,所以推出了三色標記算法,通過將對象分成白色、黑色、灰色來標記哪些對象是存活的,哪么對象需要回收。

(3)三色標記算法會產(chǎn)生多標和漏標問題,其中漏標問題最嚴重。漏標問題會導致本該存活的對象被回收,從而導致嚴重的程序問題。 CMS垃圾回收器采用了增量更新方式解決漏標問題,G1垃圾回收器采用了原始快照方式解決漏標問題。

責任編輯:武曉燕 來源: 龍蝦編程
相關推薦

2023-01-08 13:46:49

2021-08-16 10:35:52

JVM標記法屏障

2022-08-15 08:01:00

三色標記JVM算法

2021-08-06 11:46:46

Go三色標記法

2022-03-21 11:33:11

JVM垃圾回收器垃圾回收算法

2022-01-20 10:34:49

JVM垃圾回收算法

2017-08-04 10:53:30

回收算法JVM垃圾回收器

2009-12-25 16:15:31

JVM垃圾回收算法

2021-11-05 15:23:20

JVM回收算法

2024-05-23 12:40:06

2023-06-19 07:12:51

JVM三色標記

2020-07-09 15:45:22

GoGC內(nèi)存

2012-01-09 16:53:36

JavaJVM

2022-06-10 07:13:29

JVM垃圾回收

2009-12-30 10:14:29

JVM垃圾回收

2022-06-22 09:54:45

JVM垃圾回收Java

2023-08-08 10:29:55

JVM優(yōu)化垃圾回收

2010-09-26 13:29:46

JVM垃圾回收

2010-01-14 11:28:54

JVM分代垃圾回收

2010-09-25 15:33:19

JVM垃圾回收
點贊
收藏

51CTO技術棧公眾號