搜尋
首頁後端開發Golanggo語言有垃圾回收嗎

go語言有垃圾回收嗎

Dec 09, 2022 pm 07:42 PM
gogolanggo語言垃圾回收

go語言有垃圾回收。 Go語言自帶垃圾回收機制(GC);GC透過獨立的進程執行,它會搜尋不再使用的變量,並將其釋放。在計算中。記憶體空間包含兩個重要的區域:堆疊區(Stack) 和堆疊區(Heap);棧區一般儲存了函數呼叫的參數、返回值以及局部變量,不會產生記憶體碎片,由編譯器管理,無需開發者管理;而堆區會產生記憶體碎片,在Go語言中堆區的物件由記憶體分配器分配並由垃圾收集器回收。

go語言有垃圾回收嗎

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

Go語言自備垃圾回收機制(GC)。 GC 透過獨立的進程執行,它會搜尋不再使用的變量,並將其釋放。需要注意的是,GC 在運作時會佔用機器資源。

Go 語言中的垃圾回收機制GC 詳解

在電腦科學中,垃圾回收(Garbage Collection 簡稱GC) 是一種自動管理記憶體的機制,垃圾回收器會去嘗試回收程式不再使用的物件及佔用的記憶體

程式設計師受益於GC,無需操心、也不再需要對記憶體進行手動的申請和釋放操作,GC 在程式運行時自動釋放殘留的記憶體
GC 對程式設計師幾乎不可見,僅在程式需要進行特殊最佳化時,透過提供可調控的API,對GC 的運行時機、運行開銷進行把控的時候才得以現身

在運算中,記憶體空間包含兩個重要的區域:堆疊區(Stack) 和堆疊區(Heap);堆疊區一般儲存了函數呼叫的參數、傳回值以及局部變量,不會產生記憶體碎片,由編譯器管理,無需開發者管理;而堆區會產生記憶體碎片,在Go 語言中堆區的物件由記憶體分配器分配並由垃圾收集器回收。 【相關推薦:Go影片教學程式教學

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

  • 使用者程式(Mutator):使用者程式碼,對於GC 而言,使用者態程式碼僅僅只是在修改物件之間的參考關係
  • 收集器(Colletor):負責執行垃圾回收的代碼

一、記憶體管理與分配

當記憶體不再使用時,Go 記憶體管理由其標準庫自動執行,即從記憶體分配到Go 集合。記憶體管理一般包含三個不同的元件,分別是使用者程式(Mutator)、分配器(Allocator) 和收集器(Collector),當使用者程式申請記憶體時,它會透過記憶體分配器申請新內存,而分配器會負責從堆中初始化對應的記憶體區域

go語言有垃圾回收嗎

#1.1 記憶體分配器的分配方法

在程式語言中,記憶體分配器一般有兩種分配方法:

  • 線性分配器(Sequential Allocator,Bump Allocator)

  • 空閒鍊錶分配器(Free-List Allocator)

線性分配器

線性分配(Bump Allocator) 是一種高效率的記憶體分配方法,但是有較大的限制。當使用者使用線性分配器時,只需要在內存中維護一個指向內存特定位置的指針,如果用戶程式向分配器申請內存,分配器只需要檢查剩餘的空閒內存、返回分配的內存區域並修改指針在記憶體中的位置;

雖然線性分配器有較快的執行速度以及較低的實作複雜度,但線性分配器無法在記憶體釋放後重複使用記憶體。如下圖,如果已經分配的記憶體被回收,線性分配器無法重新利用紅色的記憶體

go語言有垃圾回收嗎

#因此線性分配器需要與適合的垃圾回收演算法配合使用

  • 標記壓縮(Mark-Compact)

  • 複製回收(Copying GC)

  • 分代回收(Generational GC)

以上演算法可以透過拷貝的方式整理存活物件的碎片,將空閒記憶體定期合併,這樣就能利用線性分配器的效率提升記憶體分配器的效能了

空閒鍊錶分配器

空閒鍊錶分配器(Free-List Allocator) 可以重用已經被釋放的內存,它在內部會維護一個類似鍊錶的資料結構。當使用者程式申請記憶體時,空閒鍊錶分配器會依序遍歷空閒的記憶體區塊,找到足夠大的內存,然後申請新的資源並修改鍊錶

go語言有垃圾回收嗎

空閒鍊錶分配器常見有四個策略:

  • #第一次適應(First-Fit) — 從鍊錶頭開始遍歷,選擇第一個大小大於申請記憶體的記憶體區塊
  • 循環首次適應(Next-Fit) — 從上次遍歷的結束位置開始遍歷,選擇第一個大小大於申請記憶體的記憶體區塊
  • 最優適應(Best-Fit) — 從鍊錶頭遍歷整個鍊錶,選擇最合適的記憶體區塊
  • 隔離適應(Segregated-Fit) — 將記憶體分割成多個鍊錶,每個鍊錶中的記憶體區塊大小相同,申請記憶體時先找到滿足條件的鍊錶,再從鍊錶中選擇合適的記憶體區塊

#其中第四中策略與Go 語言中使用的記憶體分配策略相似

go語言有垃圾回收嗎

該策略會將記憶體分割成由4、8、16、32 位元組的記憶體區塊組成的鍊錶,當我們向記憶體分配器申請8 位元組的記憶體時,它會在上圖中找到滿足條件的空閒記憶體區塊並返回。隔離適應的分配策略減少了需要遍歷的記憶體區塊數量,提高了記憶體分配的效率

#1.2 Go 中的記憶體分配

##一張圖展示記憶體分配組成:

go語言有垃圾回收嗎

在Go 語言中,堆上的所有物件都會透過呼叫

runtime.newobject 函數分配內存,該函數會呼叫runtime.mallocgc 分配指定大小的記憶體空間,這也是使用者程式向堆上申請記憶體空間的必經函數

func mallocgc(size uintptr, typ *_type, needzero bool) unsafe.Pointer {
	mp := acquirem()
	mp.mallocing = 1

	c := gomcache()
	var x unsafe.Pointer
	noscan := typ == nil || typ.ptrdata == 0
	if size 從程式碼中可以看出<p>runtime .mallocgc<code> 根據物件的大小執行不同的分配邏輯,根據物件大小將它們分成微物件、小物件和大物件</code></p>
    微物件
  • (0, 16B) — 先使用微型分配器,再依序嘗試執行緒快取、中心快取和堆分配記憶體
  • 小物件
  • [16B, 32KB] — 依序嘗試使用執行緒快取、中心快取和堆分配記憶體
  • 大物件
  • (32KB, ∞) — 直接在堆上分配記憶體

go語言有垃圾回收嗎

小分配

對於小於32kb 的小分配,Go 會嘗試從

mcache 的本地快取中獲取內存,該緩存處理一個跨度列表(32kb 的內存塊) mspan

go語言有垃圾回收嗎

每個執行緒M 都分配給一個處理器P,一次最多處理一個

goroutine。在分配記憶體時,目前的goroutine 將使用其目前的本機快取P 來尋找span 清單中第一個可用的空閒物件

##大分配

Go 不使用本機快取管理大型分配。這些大於32kb 的分配被四捨五入到頁面大小,頁面直接分配到堆中

go語言有垃圾回收嗎

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

Roth回收器與Go 程式同時運行,因此需要透過一種

寫入屏障

演算法來偵測記憶體中的潛在變化。啟動寫入屏障的唯一條件是在短時間內停止程序,即「Stop the World」

go語言有垃圾回收嗎

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

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

go語言有垃圾回收嗎

#清除終止階段

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

#

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

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

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

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

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

標記終止階段(STW)

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

## 清理階段

    ##將狀態切換至
  • _GCoff

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

  • 恢復使用者程序,所有新建立的物件都會標記成白色
  • 後台並發清理所有的記憶體管理單元,當Goroutine 申請新的記憶體管理單元時就會觸發清理

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

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

    從灰色物件的集合中選擇一個灰色物件並將其標記成黑色
  • 將黑色物件指向的所有物件都標記成灰色,保證該物件和被該物件所引用的物件都不會被回收
  • 重複上述兩個步驟直到物件圖中不存在灰色對象

1go語言有垃圾回收嗎更多程式相關知識,請造訪:

程式設計影片

! !

以上是go語言有垃圾回收嗎的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
Golang:Go編程語言解釋了Golang:Go編程語言解釋了Apr 10, 2025 am 11:18 AM

Go語言的核心特性包括垃圾回收、靜態鏈接和並發支持。 1.Go語言的並發模型通過goroutine和channel實現高效並發編程。 2.接口和多態性通過實現接口方法,使得不同類型可以統一處理。 3.基本用法展示了函數定義和調用的高效性。 4.高級用法中,切片提供了動態調整大小的強大功能。 5.常見錯誤如競態條件可以通過gotest-race檢測並解決。 6.性能優化通過sync.Pool重用對象,減少垃圾回收壓力。

Golang的目的:建立高效且可擴展的系統Golang的目的:建立高效且可擴展的系統Apr 09, 2025 pm 05:17 PM

Go語言在構建高效且可擴展的系統中表現出色,其優勢包括:1.高性能:編譯成機器碼,運行速度快;2.並發編程:通過goroutines和channels簡化多任務處理;3.簡潔性:語法簡潔,降低學習和維護成本;4.跨平台:支持跨平台編譯,方便部署。

SQL排序中ORDER BY語句結果為何有時看似隨機?SQL排序中ORDER BY語句結果為何有時看似隨機?Apr 02, 2025 pm 05:24 PM

關於SQL查詢結果排序的疑惑學習SQL的過程中,常常會遇到一些令人困惑的問題。最近,筆者在閱讀《MICK-SQL基礎�...

技術棧收斂是否僅僅是技術棧選型的過程?技術棧收斂是否僅僅是技術棧選型的過程?Apr 02, 2025 pm 05:21 PM

技術棧收斂與技術選型的關係在軟件開發中,技術棧的選擇和管理是一個非常關鍵的問題。最近,有讀者提出了...

如何在Go語言中使用反射對比並處理三個結構體的差異?如何在Go語言中使用反射對比並處理三個結構體的差異?Apr 02, 2025 pm 05:15 PM

Go語言中如何對比並處理三個結構體在Go語言編程中,有時需要對比兩個結構體的差異,並將這些差異應用到第�...

在Go語言中如何查看全局安裝的包?在Go語言中如何查看全局安裝的包?Apr 02, 2025 pm 05:12 PM

在Go語言中如何查看全局安裝的包?在使用Go語言開發過程中,經常會使用go...

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

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

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
3 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能