GC簡介
Go GC(Garbage Collection)垃圾回收是一種自動管理內存的方式.支持GC的語言無需手動管理內存,程序後臺自動判斷對象,是否存活並回收其內存空間,使開發人員從內存管理上解脫出來.
垃圾回收分類
- 引用計數 C++ std庫,cocos2d
- 標記清楚
- 三色標記 go,
- 分代收集 java, .net
go使用的是三色標記
由來: 1959年,GC由John McCarthy 發明,用於Lisp中的手動內存管理,現在很多語言都提供了GC,不過GC的原理和基本算法並沒有太大改變.
go GC的發展
Golang 早起版本GC問題可能較多,好在,每一個版本發佈GC都有所改進
- 1.5版(2015.8)本之後,Go GC已經能滿足大部分生產環境的使用要求; 加入了三色標記發,併發清除標記清除
- 1.8 (2017.2)通過混合寫入屏障,使得STW(stop the world) 降到了sub ms; 增加了hybrid write barrier(混合寫屏障)
Go GC特徵
- 三色標記
- 併發標記和清掃
- 非分代
- 非緊縮
- 混合寫屏障
三色標記
參考: https://en.wikipedia.org/wiki/Tracing_garbage_collection
- 程序開始時有黑白灰三個集合,初始時所有對象都是白色
- 從root對象開始標記,將所有可達對象標記爲灰色
- 從灰色對象集合取出對象,將其引用對象標記爲灰色,放入灰色集合,並將自己標記標記爲黑色
- 重複第三步,直到灰色集合爲空,即所有可達對象全部都被標記
- 標記結束後,不可達白色對象即爲垃圾,對內存進行迭代清掃,回收白色對象
- 重置GC狀態
寫屏障
指針在賦值之前會開啓寫屏障;操作完成之後,關閉,回調之前的代碼,保證垃圾回收機制完整,保證沒有漏標記的對象;
三色狀態
在GC中,並沒有真正的三個集合來分別裝三色對象;
go的想分配實在span中的,span裏還有一個字段是gcmarkBits, mark階段裏面每個bit代表一個slot已被標記
白色對象該bit爲0,灰色或者黑色爲1(runtime.markBits); 白色會被回收
每個p中都有wbBuf和gcw gcWork,以及全局workbuf標記隊列,實現生產者-消費者模型,在隊列中的指針爲灰色對象,表示已標記,待掃描