Go語言帶你一起飛--Go的垃圾回收
相信熟悉某一門程式語言的攻城獅們,對它的垃圾回收一定不陌生,是不是曾經不止一次地受到jvm給準備的oom彩蛋!就問你:驚不驚喜,驚不驚悚?!
前段時間自己研究了一下Go語言,時隔這麼些天,總該有這麼一個機會將自己對Go的認知做一下沉澱,但相對於之前的系列部落格,腦門一熱打算先從它的垃圾回收開始整理,這裡將結合一些java中的垃圾回收演算法來做對比;對於java,我們可以從多個角度來看它的垃圾回收演算法:
▶ 按照基本回收策略來分,有引用計數、標記-清除、複製、標記-整理
▶ 按照分割槽對待的方式來分,有增量收集和分代收集兩種;
▶ 按照系統執行緒來分,有序列收集和並行收集,併發收集三種;【詳情見:
在Go中的垃圾回收演算法和jvm的垃圾回收演算法一樣,也是從“stop the world”開始的,並且Go中的GC是固定每分鐘執行一次,而每次GC的消耗時間是與垃圾回收的物件數量相關的,垃圾回收時會掃描需要回收的記憶體區域,如果發現物件的內容彙總包含指標,就會遞迴地進行掃描;所以從一定程度上,Go中的垃圾回收更偏向於標記-清除演算法;
在Go的1.3版本開始對Go的gc效能進行持續的改進和優化,在該版本中,Go runtime分離了mark和sweep的操作,和之前版本一樣,在gc之前需要先暫停所有任務並啟動mark(stop the world),mark 完之後馬上重新啟動被暫停的任務,然後讓sweep的任務和普通協程(
在之後的1.4版本沒有對GC做太多變更,只是將之前很多的原生c語言變換為Go語言來實現,對於go來說這次的變動可以更好更精確地實現gc;因為C語言在實現GC時不能獲取到記憶體的物件資訊,因此無法區分普通變數和指標;
1.5版本中,改進的主要目標是減少延遲,因此實現的垃圾回收器是“非分代、非移動、併發的、三色的標記清除垃圾收集器”,而三色標記法的mark操作是可以漸進執行的而不需要每次都掃描整個記憶體空間,進而減少stop the world的時間。
從整體上來講,go語言中的GC有了很大的改進,但是還需要在優化的路上繼續前進;