千鋒教育-做有情懷、有良心、有品質的職業教育機構

Golang內存管理:GC算法剖析

前言
作為一門高性能的編程語言,Golang內存管理一直是開發者們關注的重點。作為Golang工程師,不了解內存管理會使得我們的代碼出現內存泄漏等問題。因此,本文旨在深入探討Golang的GC算法。
1. Golang GC 算法分類
Golang目前使用的是三色標記和清除算法(3-color Mark and Sweep),和Java的標記清除算法類似,一般分為以下幾個步驟:
1) 根搜索(Root scanning):從固定的根開始掃描調用關系,標記被引用的對象。
2) 標記(Marking):從根對象開始,遍歷整個堆,將被引用的對象標記為黑色。
3) 清除(Sweeping):將所有未被標記的對象清除,并將空間恢復給空閑鏈表。
2. 標記算法原理
2.1 標記時機
Golang運行時會分配一部分內存作為heap(堆),當堆中的對象達到一定的比例后,就會觸發GC,進行垃圾回收。
2.2 標記流程
* GC開始前,所有對象都是白色的,標記位為0。
* 然后從根出發,遍歷所有對象,將其標記為灰色,標記位為1,放入灰色對象隊列
* 遍歷灰色對象隊列,取出一個對象,將其標記為黑色,所有引用它的對象也被標記后,放入黑色對象隊列。
* 如果隊列為空,則標記結束,所有沒被標記的對象都是垃圾,可以被回收了。
2.3 并發標記
在并發標記中,會出現三色標記問題,即黑色對象引用灰色和白色對象,在標記結束前,灰色和白色對象之間還有引用關系,這時不能將所有白色對象都回收掉。因此Golang引入了三色標記和清除算法。
3. 三色標記和清除算法
3.1 狀態
Golang中的對象有三種狀態:黑色、灰色、白色。
* 黑色:已標記為存活的對象。
* 灰色:已發現但未標記為存活的對象。
* 白色:未發現的對象。
3.2 標記
在標記過程中,首先將根對象標記為灰色,并將灰色對象入隊。然后遍歷灰色隊列,將灰色對象標記為黑色,將灰色對象的引用的白色對象標記為灰色,入隊。不斷遍歷灰色隊列,直到隊列為空。
3.3 清除
清除階段中,將所有白色對象回收,并將黑色和灰色對象標記為白色。
4. 安全點和邊界棧
為了避免在標記時,出現指向新生代對象的指針,Golang使用了安全點和邊界棧。
安全點是Golang程序執行期間,在程序整個執行過程中的某一時刻,GC程序可以安全地執行垃圾回收操作的時刻。Golang GC會在每個安全點進行檢查,如果發現條件滿足,則啟動GC,并在安全點結束時恢復GC。
邊界棧用于記錄函數的退出地址,避免遍歷調用棧時出現指向新生代的指針。
5. 總結
Golang內存管理采用了三色標記和清除算法,在并發標記時,使用了狀態標記和安全點的方法來保證垃圾回收的準確性和高效性。同時,Golang GC 內部還有一組邊界棧數據結構,來防止指針指向新生代對象,提升了GC的性能。
上一篇
如何使用Go語言進行Web開發?下一篇
如何快速學習Golang專家建議
相關推薦