圖解Golang的GC算法

雖然Golang的GC自打一開始,就被人所詬病,可是通過這麼多年的發展,Golang的GC已經改善了很是多,變得很是優秀了。golang

如下是Golang GC算法的里程碑:算法

  • v1.1 STW
  • v1.3 Mark STW, Sweep 並行
  • v1.5 三色標記法
  • v1.8 hybrid write barrier

經典的GC算法有三種:引用計數(reference counting)標記-清掃(mark & sweep)複製收集(Copy and Collection)安全

Golang的GC算法主要是基於標記-清掃(mark and sweep)算法,並在此基礎上作了改進。所以,在此主要介紹一下標記-清掃(mark and sweep)算法,關於引用計數(reference counting)和複製收集(copy and collection)可自行百度。微信

標記-清掃(Mark And Sweep)算法

此算法主要有兩個主要的步驟:markdown

  • 標記(Mark phase)
  • 清除(Sweep phase)

第一步,找出可達的對象,而後作上標記。 第二步,回收未標記的對象。併發

操做很是簡單,可是有一點須要額外注意:mark and sweep算法在執行的時候,須要程序暫停!即stop the world。 也就是說,這段時間程序會卡在哪兒。故中文翻譯成卡頓oop

咱們來看一下圖解:spa

開始標記,程序暫停。程序和對象的此時關係是這樣的:線程

而後開始標記,process找出它全部可達的對象,並作上標記。以下圖所示:翻譯

標記完了以後,而後開始清除未標記的對象:

而後垃圾清除了,變成了下圖這樣。

最後,中止暫停,讓程序繼續跑。而後循環重複這個過程,直到process生命週期結束。

標記-清掃(Mark And Sweep)算法存在什麼問題?

標記-清掃(Mark And Sweep)算法這種算法雖然很是的簡單,可是還存在一些問題:

  • STW,stop the world;讓程序暫停,程序出現卡頓。
  • 標記須要掃描整個heap
  • 清除數據會產生heap碎片

這裏面最重要的問題就是:mark-and-sweep 算法會暫停整個程序。

Go是如何面對並這個問題的呢?

三色併發標記法

咱們先來看看Golang的三色標記法的大致流程。

首先:程序建立的對象都標記爲白色。

gc開始:掃描全部可到達的對象,標記爲灰色

從灰色對象中找到其引用對象標記爲灰色,把灰色對象自己標記爲黑色

監視對象中的內存修改,並持續上一步的操做,直到灰色標記的對象不存在

此時,gc回收白色對象。

最後,將全部黑色對象變爲白色,並重復以上全部過程。

好了,大致的流程就是這樣的,讓咱們回到剛纔的問題:Go是如何解決標記-清除(mark and sweep)算法中的卡頓(stw,stop the world)問題的呢?

gc和用戶邏輯如何並行操做?

標記-清除(mark and sweep)算法的STW(stop the world)操做,就是runtime把全部的線程所有凍結掉,全部的線程所有凍結意味着用戶邏輯是暫停的。這樣全部的對象都不會被修改了,這時候去掃描是絕對安全的。

Go如何減短這個過程呢?標記-清除(mark and sweep)算法包含兩部分邏輯:標記和清除。 咱們知道Golang三色標記法中最後只剩下的黑白兩種對象,黑色對象是程序恢復後接着使用的對象,若是不碰觸黑色對象,只清除白色的對象,確定不會影響程序邏輯。因此:清除操做和用戶邏輯能夠併發。

標記操做和用戶邏輯也是併發的,用戶邏輯會時常生成對象或者改變對象的引用,那麼標記和用戶邏輯如何併發呢?

process新生成對象的時候,GC該如何操做呢?不會亂嗎?

咱們看以下圖,在此狀態下:process程序又新生成了一個對象,咱們設想會變成這樣:

可是這樣顯然是不對的,由於按照三色標記法的步驟,這樣新生成的對象A最後會被清除掉,這樣會影響程序邏輯。

Golang爲了解決這個問題,引入了寫屏障這個機制。 寫屏障:該屏障以前的寫操做和以後的寫操做相比,先被系統其它組件感知。 通俗的講:就是在gc跑的過程當中,能夠監控對象的內存修改,並對對象進行從新標記。(實際上也是超短暫的stw,而後對對象進行標記)

在上述狀況中,新生成的對象,一概都標位灰色! 即下圖:

那麼,灰色或者黑色對象的引用改成白色對象的時候,Golang是該如何操做的?

看以下圖,一個黑色對象引用了曾經標記的白色對象。

這時候,寫屏障機制被觸發,向GC發送信號,GC從新掃描對象並標位灰色。

所以,gc一旦開始,不管是建立對象仍是對象的引用改變,都會先變爲灰色。

參考文獻:

更多精彩內容,請關注個人微信公衆號 互聯網技術窩 或者加微信共同探討交流:

相關文章
相關標籤/搜索