golang的記憶體回收(GC)機制

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。


請先閱讀 golang的goroutine調度機制

然後再到這裡

 

golang的記憶體回收採用的是 標記-清理(Mark-and-Sweep) 演算法

就是先標記出需要回收的記憶體對象快,然後在清理掉;

在這裡不介紹標記和清理的具體策略,只介紹 GC過程是怎麼調度的以及stw相關

這個演算法,會導致 stw (stop the world)的問題,中斷使用者邏輯

觸發GC機制

1.    在申請記憶體的時候,檢查當前當前已指派的記憶體是否大於上次GC後的記憶體的2倍,若是則觸發(主GC線程為當前M)

2.    監控線程發現上次GC的時間已經超過兩分鐘了,觸發;將一個G任務放到全域G隊列中去。(主GC線程為執行這個G任務的M)

 

每當觸發的時候,在主GC線程中就會走如下的GC流程:

1.    stop the world,等待所有的M休眠;此時所有的商務邏輯代碼都停止

2.    標記:分配gc標記任務,喚醒 gcproc個 M(就是第一步休眠的那些),分別做這個,直到所有的M都做完,才結束;並且所有M再次進入休眠

3.    清理:有一個單獨的goroutine去清理已經標記的記憶體對象快

4.    start the world,設置gcwaiting=0,喚醒所有的M(不會超過P個數)

 

對於上面的三個步驟,分別解釋:

stop the world:

1.    設定gcwaiting=1,這個在每一個G任務之前會檢查一次這個狀態,如是,則會將當前M休眠;

2.    如果這個M裡面正在運行一個長時間的G任務,咋辦呢,難道會等待這個G任務自己切換嗎?這樣的話可要等10ms啊,不能等!堅決不能等!
所以會主動發出搶占標記(類似於上一篇),讓當前G任務中斷,再運行下一個G任務的時候,就會走到第1步

3.    一直等待所有的M進入休眠,此時所有的商務邏輯代碼都停止

標記:

1.     根據gcproc的個數,分配成gcproc任務段;喚醒gcproc-1個M來執行(當前M也算一個)

2.    對於一個M,喚醒前設定它的helpgc標記,喚醒之後這個M會立馬判斷這個標記,如是,則開始做分配給自己的標記任務,如果先做完了,就會從別的M裡面找一些來做

3.    等每一個M都做完,會再次進入休眠

清理:

1.    通過設置參數,可以以一個單獨goroutine  運行,這個功能是在1.3版本之後增加的,這樣的話就直接到下一步了,清理過程不是stw的

2.    也可以串列的在主GC線程執行;這樣的話則清理過程也是stw的,

start the world:

1.    設定gcwaiting=0

2.    喚醒P個M來繼續做G任務(此時沒有helpgc標記),商務邏輯代碼開始

 

 

綜上:

是基於1.4版本的,GC過程在標記過程是(STW)的

在1.5版本裡面對GC做了很大的最佳化;採用三色標記,將標記過程細化成三段,只有前後的兩段是stw的;極大地縮短了gc的stw時間

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.