首頁 後端開發 Golang go語言需要手動管理記憶體嗎

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

Dec 16, 2022 pm 03:05 PM
go語言

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

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

本教學操作環境: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 語言中,垃圾回收器實作的演算法是一個並發的三色標記和掃描收集器

啟動寫入屏障的唯一條件是在短時間內停止程序,即「Stop the World」

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

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

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

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

#清除終止階段

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

    #將狀態切換至
  • _GCmark

    、開啟寫入屏障、使用者程式協助(Mutator Assists)並將根物件入隊

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

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

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

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

#標記終止階段(STW)

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

##清理階段

  • 將狀態切換至

    _GCoff 開始清理階段,初始化清理狀態並關閉寫入屏障

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

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

1.2 三色標記法

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

    白色物件— 潛在的垃圾,其記憶體可能會被垃圾收集器回收
  • 黑色物件— 活躍的對象,包括不存在任何引用外部指標的物件以及從根物件可達的物件
  • 灰色物件— 活躍的對象,因為存在指向白色物件的外部指針,垃圾收集器會掃描這些物件的子物件
三色標記垃圾收集器的工作原理很簡單,可以將其歸納成以下幾個步驟:

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

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

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

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

更多程式相關知識,請造訪:

程式設計影片! !

以上是go語言需要手動管理記憶體嗎的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

Go語言中用於浮點數運算的庫有哪些? Go語言中用於浮點數運算的庫有哪些? Apr 02, 2025 pm 02:06 PM

Go語言中用於浮點數運算的庫介紹在Go語言(也稱為Golang)中,進行浮點數的加減乘除運算時,如何確保精度是�...

Go的爬蟲Colly中Queue線程的問題是什麼? Go的爬蟲Colly中Queue線程的問題是什麼? Apr 02, 2025 pm 02:09 PM

Go爬蟲Colly中的Queue線程問題探討在使用Go語言的Colly爬蟲庫時,開發者常常會遇到關於線程和請求隊列的問題。 �...

GoLand中自定義結構體標籤不顯示怎麼辦? GoLand中自定義結構體標籤不顯示怎麼辦? Apr 02, 2025 pm 05:09 PM

GoLand中自定義結構體標籤不顯示怎麼辦?在使用GoLand進行Go語言開發時,很多開發者會遇到自定義結構體標籤在�...

在 Go 語言中,為什麼使用 Println 和 string() 函數打印字符串會出現不同的效果? 在 Go 語言中,為什麼使用 Println 和 string() 函數打印字符串會出現不同的效果? Apr 02, 2025 pm 02:03 PM

Go語言中字符串打印的區別:使用Println與string()函數的效果差異在Go...

在Go語言中使用Redis Stream實現消息隊列時,如何解決user_id類型轉換問題? 在Go語言中使用Redis Stream實現消息隊列時,如何解決user_id類型轉換問題? Apr 02, 2025 pm 04:54 PM

Go語言中使用RedisStream實現消息隊列時類型轉換問題在使用Go語言與Redis...

Go語言中`var`和`type`關鍵字定義結構體的區別是什麼? Go語言中`var`和`type`關鍵字定義結構體的區別是什麼? Apr 02, 2025 pm 12:57 PM

Go語言中結構體定義的兩種方式:var與type關鍵字的差異Go語言在定義結構體時,經常會看到兩種不同的寫法:一�...

Go語言中哪些庫是由大公司開發或知名的開源項目提供的? Go語言中哪些庫是由大公司開發或知名的開源項目提供的? Apr 02, 2025 pm 04:12 PM

Go語言中哪些庫是大公司開發或知名開源項目?在使用Go語言進行編程時,開發者常常會遇到一些常見的需求,�...

在Go編程中,如何正確管理Mysql和Redis的連接與釋放資源? 在Go編程中,如何正確管理Mysql和Redis的連接與釋放資源? Apr 02, 2025 pm 05:03 PM

Go編程中的資源管理:Mysql和Redis的連接與釋放在學習Go編程過程中,如何正確管理資源,特別是與數據庫和緩存�...

See all articles