go語言需要手動管理記憶體嗎

2022-12-16 18:00:59

go語言不需要手動管理記憶體;go語言內建記憶體管理功能(GC機制),是一種自動記憶體管理的機制。當程式向作業系統申請的記憶體不再需要時,垃圾回收主動將其回收並供其他程式碼進行記憶體申請時候複用,或者將其歸還給作業系統,這種針對記憶體級別資源的自動回收過程,即為垃圾回收;而負責垃圾回收的程式元件,即為垃圾回收器。

php入門到就業線上直播課:進入學習
Apipost = Postman + Swagger + Mock + Jmeter 超好用的API偵錯工具:

本教學操作環境:windows7系統、GO 1.18版本、Dell G3電腦。

go語言不需要手動管理記憶體;go語言內建記憶體管理功能(GC機制),開發者不需要關心記憶體的申請和釋放,這樣為使用者帶來極大的便利。

什麼是GC,又有什麼用?

GC,全稱 Garbage Collection,即垃圾回收,是一種自動記憶體管理的機制。

當程式向作業系統申請的記憶體不再需要時,垃圾回收主動將其回收並供其他程式碼進行記憶體申請時候複用,或者將其歸還給作業系統,這種針對記憶體級別資源的自動回收過程,即為垃圾回收。而負責垃圾回收的程式元件,即為垃圾回收器。

垃圾回收其實一個完美的 「Simplicity is Complicated」 的例子。一方面,程式設計師受益於 GC,無需操心、也不再需要對記憶體進行手動的申請和釋放操作,GC 在程式執行時自動釋放殘留的記憶體。另一方面,GC 對程式設計師幾乎不可見,僅在程式需要進行特殊優化時,通過提供可調控的 API,對 GC 的執行時機、執行開銷進行把控的時候才得以現身。

在計算中,記憶體空間包含兩個重要的區域:棧區 (Stack) 和堆區 (Heap);棧區一般儲存了函數呼叫的引數、返回值以及區域性變數,不會產生記憶體碎片,由編譯器管理,無需開發者管理;而堆區會產生記憶體碎片,在 Go 語言中堆區的物件由記憶體分配器分配並由垃圾收集器回收

通常,垃圾回收器的執行過程被劃分為兩個半獨立的元件:

  • 賦值器(Mutator):這一名稱本質上是在指代使用者態的程式碼。因為對垃圾回收器而言,使用者態的程式碼僅僅只是在修改物件之間的參照關係,也就是在物件圖(物件之間參照關係的一個有向圖)上進行操作。

  • 回收器(Collector):負責執行垃圾回收的程式碼。

GC中的根物件

根物件在垃圾回收的術語中又叫做根集合,它是垃圾回收器在標記過程時最先檢查的物件,包括:

  • 全域性變數:程式在編譯期就能確定的那些存在於程式整個生命週期的變數。

  • 執行棧:每個 goroutine 都包含自己的執行棧,這些執行棧上包含棧上的變數及指向分配的堆記憶體區塊的指標。

  • 暫存器:暫存器的值可能表示一個指標,參與計算的這些指標可能指向某些賦值器分配的堆記憶體區塊。

垃圾回收

在 Go 語言中,垃圾回收器實現的演演算法是一個並行的三色標記和掃描收集器

垃回收器與 Go 程式同時執行,因此需要通過一種演演算法來檢測記憶體中的潛在變化。啟動寫屏障的唯一條件是在短時間內停止程式,即 「Stop the World」

9.png

寫屏障的目的是允許收集器在收集期間保持堆上的資料完整性

1.1 實現原理

Go 語言的垃圾收集可以分成清除終止、標記、標記終止和清除四個不同的階段,其中兩個階段會產生 Stop The World (STW)

10.png

清除終止階段

  • 暫停程式,所有的處理器在這時會進入安全點(Safe point)
  • 如果當前垃圾收集迴圈是強制觸發的,我們還需要處理還未被清理的記憶體管理單元

標記階段 (STW)

  • 將狀態切換至 _GCmark、開啟寫屏障、使用者程式協助(Mutator Assists)並將根物件入隊

  • 恢復執行程式,標記程序和用於協助的使用者程式會開始並行標記記憶體中的物件,寫屏障會將被覆蓋的指標和新指標都標記成灰色,而所有新建立的物件都會被直接標記成黑色

  • 開始掃描根物件,包括所有 Goroutine 的棧、全域性物件以及不在堆中的執行時資料結構,掃描 Goroutine 棧期間會暫停當前處理器

  • 依次處理灰色佇列中的物件,將物件標記成黑色並將它們指向的物件標記成灰色

  • 使用分散式的終止演演算法檢查剩餘的工作,發現標記階段完成後進入標記終止階段

標記終止階段 (STW)

  • 暫停程式、將狀態切換至 _GCmarktermination 並關閉輔助標記的使用者程式
  • 清理處理器上的執行緒快取

清理階段

  • 將狀態切換至 _GCoff 開始清理階段,初始化清理狀態並關閉寫屏障

  • 恢復使用者程式,所有新建立的物件會標記成白色

  • 後臺並行清理所有的記憶體管理單元,當 Goroutine 申請新的記憶體管理單元時就會觸發清理

1.2 三色標記法

三色標記演演算法將程式中的物件分成白色、黑色和灰色三類:

  • 白色物件 — 潛在的垃圾,其記憶體可能會被垃圾收集器回收
  • 黑色物件 — 活躍的物件,包括不存在任何參照外部指標的物件以及從根物件可達的物件
  • 灰色物件 — 活躍的物件,因為存在指向白色物件的外部指標,垃圾收集器會掃描這些物件的子物件

三色標記垃圾收集器的工作原理很簡單,可以將其歸納成以下幾個步驟:

  • 從灰色物件的集合中選擇一個灰色物件並將其標記成黑色

  • 將黑色物件指向的所有物件都標記成灰色,保證該物件和被該物件參照的物件都不會被回收

  • 重複上述兩個步驟直到物件圖中不存在灰色物件

11.png

更多程式設計相關知識,請存取:!!

以上就是go語言需要手動管理記憶體嗎的詳細內容,更多請關注TW511.COM其它相關文章!