欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解Golang的GC三色標記法

 更新時間:2023年05月16日 09:54:33   作者:wangxiaoangg  
這篇文章主要為大家介紹了Golang的GC三色標記法,文中有詳細的實現(xiàn)過程供大家參考,對大家的學習或工作有一定幫助,感興趣的可以跟著小編一來看看

一 概念基礎

1.1三色標記法將對象分為三類

把圖過程中遇到的對象,按“是否訪問過”這個條件標記成以下三種顏色:

白色對象(可能死亡):未被回收器訪問到的對象。在回收開始階段,所有對象均為白色,當回收結束后,白色對象均不可達。

灰色對象(波面):已被回收器訪問到的對象,但回收器需要對其中的一個或多個指針進行掃描,因為他們可能還指向白色對象。

黑色對象(確定存活):已被回收器訪問到的對象,其中所有字段都已被掃描,黑色對象中任何一個指針都不可能直接指向白色對象。

1.2 標記過程

  • 起初所有的對象都是白色的;
  • 從根對象出發(fā)掃描所有可達對象,標記為灰色,放入待處理隊列;
  • 從待處理隊列中取出灰色對象,將其引用的對象標記為灰色并放入待處理隊列中,自身標記為黑色;
  • 重復步驟3,直到待處理隊列為空,此時白色對象即為不可達的“垃圾”,回收白色對象;
  • 回收所有的白色對象,也就是回收垃圾

根對象

在垃圾回收的術語中又叫做根集合,它是垃圾回收器在標記過程時最先檢查的對象。

  • 全局變量:程序在編譯期就能確定的那些存在于程序整個生命周期的變量。
  • 執(zhí)行棧:每個 goroutine 都包含自己的執(zhí)行棧,這些執(zhí)行棧上包含棧上的變量及指向分配的堆內存區(qū)塊的指針。
  • 寄存器:寄存器的值可能表示一個指針,參與計算的這些指針可能指向某些賦值器分配的堆內存區(qū)塊。

1.3 STW

STW(Stop The World)機制是指在進行垃圾回收時,會暫停應用程序的運行,以便進行垃圾回收操作。這意味著在進行垃圾回收時,應用程序將無法繼續(xù)執(zhí)行。

為什么需要STW

STW(Stop-The-World)機制來確保并發(fā)操作的正確性。

如果不設置STW機制,那么在進行GC時,應用程序線程可能會繼續(xù)執(zhí)行,從而導致內存管理的不一致性和錯誤。此外,GC可能會導致內存分配和釋放的不連續(xù),從而導致內存碎片化問題。

因此,需要STW機制來確保GC的正確性和內存管理的一致性。雖然STW機制會導致一定的性能損失,但是這是必要的代價,以確保應用程序的正確性和穩(wěn)定性。

1.4 屏障機制

1.4.1強、弱三色不變式

強三色不變式:強制性的不允許黑色對象引用白色對象,只能引用灰色對象,這樣就不會出現(xiàn)白色對象被誤刪的情況。

弱三色不等式 :
保護灰色對象到白色對象的路徑不會斷;

黑色對象可以引用白色對象,白色對象存在其他灰色對象對它的引用。
或可達它的鏈路上游存在灰色對象。這樣實則是黑色對象引用白色對象,白色對象處于一個被刪除的狀態(tài),但是上游灰色對象的引用,可以保護白色對象,使其安全。

為了遵循上述兩種方式,GC算法演進到兩種屏障方式,“插入屏障”和“刪除屏障”。

1.4.2 插入屏障

在A對象引用B對象時,B對象被標記為灰色。(將B掛在A下游,B必須被標記為灰色)

滿足強三色不等式。

插入屏障機制在??臻g的對象操作不使用,僅僅使用在堆空間對象的操作中。

1.4.3 刪除屏障

被刪除的對象,如果本身為灰色或白色,那么標記為灰色。

滿足弱三色不等式。

1.4.4 混合屏障

插入寫屏障和刪除寫屏障的缺點:

  • 插入寫屏障:結束時需要STW來重新掃描棧,標記棧上引用的白色對象存活
  • 刪除寫屏障:回收精度低,GC開始時STW掃描堆棧來記錄快照,這個過程會保護開始時刻的所有的存活對象。

Go1.8引入混合寫屏障機制,避免了對棧的重復掃描過程,極大減少了STW的時間。

  • GC開始將棧上的對象全部掃描并標記為黑色(之后不再進行第二次重復掃描,無需STW)
  • GC期間,任何在棧上創(chuàng)建的新對象,都標記為黑色
  • 被刪除的對象標記為灰色
  • 被添加的對象標記為灰色

二 GC過程

2.1 階段1:Mark Setup 標記準備

為了打開寫屏障,必須停止每個goroutine,讓垃圾收集器觀察并等待每個goroutine進行函數(shù)調用,等待函數(shù)調用是為了保證goroutine停止時處于安全點。(期間會STW)

2.2 階段2:Marking 標記

一旦寫屏障打開,垃圾收集器就開始標記階段。

標記階段需要標記在堆內存中仍然在使用中的值。首先檢查所有現(xiàn)goroutine的堆棧,以找到堆內存的根指針。然后收集器必須從那些根指針遍歷堆內存圖,標記可以回收的內存。

當存在新的內存分配時,會暫停分配內存過快的那些 goroutine,并將其轉去執(zhí)行一些輔助標記(Mark Assist)的工作,從而達到放緩繼續(xù)分配、輔助 GC 的標記工作的目的。

2.3階段3:Mark Termination 標記結束

這個階段會關閉掉階段1開啟的屏障,并計算下一次清理的目標和計劃。(本階段會STW)

2.4 階段4:Sweeping 清理

清理階段用于回收標記階段中標記出來的可回收內存。當應用程序goroutine嘗試在堆內存中分配新內存時,會觸發(fā)該操作,清理導致的延遲和吞吐量降低被分散到每次內存分配時。

本階段會并發(fā)執(zhí)行,清除前面標記出來需清理的內存。

以上就是詳解Golang的GC三色標記法的詳細內容,更多關于Golang GC 三色標記法的資料請關注腳本之家其它相關文章!

相關文章

  • Go語言中使用反射的方法

    Go語言中使用反射的方法

    這篇文章主要介紹了Go語言中使用反射的方法,實例分析了Go語言實現(xiàn)反射的技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-02-02
  • 一文帶你了解Go語言實現(xiàn)的并發(fā)神庫conc

    一文帶你了解Go語言實現(xiàn)的并發(fā)神庫conc

    前幾天逛github發(fā)現(xiàn)了一個有趣的并發(fā)庫-conc,這篇文章將為大家詳細介紹一下這個庫的實現(xiàn),文中的示例代碼講解詳細,感興趣的可以了解一下
    2023-01-01
  • 輕松入門:使用Golang開發(fā)跨平臺GUI應用

    輕松入門:使用Golang開發(fā)跨平臺GUI應用

    Golang是一種強大的編程語言,它的并發(fā)性和高性能使其成為開發(fā)GUI桌面應用的理想選擇,Golang提供了豐富的標準庫和第三方庫,可以輕松地創(chuàng)建跨平臺的GUI應用程序,通過使用Golang的GUI庫,開發(fā)人員可以快速構建具有豐富用戶界面和交互功能的應用程序,需要的朋友可以參考下
    2023-10-10
  • Go語言并發(fā)之context標準庫的使用詳解

    Go語言并發(fā)之context標準庫的使用詳解

    Context的出現(xiàn)是為了解決在大型應用程序中的并發(fā)環(huán)境下,協(xié)調和管理多個goroutine之間的通信、超時和取消操作的問題,本文就來和大家簡單聊聊它的具體用法,希望對大家有所幫助
    2023-06-06
  • 通過案例簡單聊聊為什么說Go中的字符串是不能被修改的

    通過案例簡單聊聊為什么說Go中的字符串是不能被修改的

    在接觸Go這么語言,可能你經(jīng)常會聽到這樣一句話,對于字符串不能修改,可能你很納悶,日常開發(fā)中我們對字符串進行修改也是很正常的,為什么又說Go中的字符串不能進行修改呢,本文就來通過實際案例給大家演示,為什么Go中的字符串不能進行修改
    2023-07-07
  • Golang應用程序性能優(yōu)化技巧分享

    Golang應用程序性能優(yōu)化技巧分享

    隨著科技的進步,人人都想要快速的應用,這就需要優(yōu)化您的應用程序性能。本文為大家整理了一些Golang應用程序性能優(yōu)化的技巧,希望對大家有所幫助
    2023-04-04
  • go語言?http模型reactor示例詳解

    go語言?http模型reactor示例詳解

    這篇文章主要介紹了go語言?http模型reactor,接下來看一段基于reactor的示例,這里運行通過?go?run?main.go,本文結合示例代碼給大家介紹的非常詳細,需要的朋友可以參考下
    2023-01-01
  • 一文詳解Golang中字符串的常見錯誤

    一文詳解Golang中字符串的常見錯誤

    這篇文章主要來和大家深入討論一下Golang?中的字符串,并查看一些不同的場景,以避免常見錯誤,對大家掌握golang有一定的幫助,需要的可以了解下
    2023-10-10
  • GoLang 逃逸分析的機制詳解

    GoLang 逃逸分析的機制詳解

    這篇文章主要介紹了GoLang-逃逸分析的機制詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-02-02
  • Golang的Fork/Join實現(xiàn)代碼

    Golang的Fork/Join實現(xiàn)代碼

    Fork/Join本質上是一種任務分解,將一個很大的任務分解成若干個小任務,然后再對小任務進一步分解,直到最小顆粒度,然后并發(fā)執(zhí)行,對Golang的Fork/Join實現(xiàn)代碼感興趣的朋友跟隨小編一起看看吧
    2023-01-01

最新評論