91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

go語言垃圾回收機制是什么樣的

發布時間:2022-12-12 10:25:42 來源:億速云 閱讀:164 作者:栢白 欄目:編程語言

今天小編給大家分享的是go語言垃圾回收機制是什么樣的,相信很多人都不太了解,為了讓大家更加了解,所以給大家總結了以下內容,一起往下看吧。一定會有所收獲的哦。

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

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 <= maxSmallSize {
		if noscan && size < maxTinySize {
			// 微對象分配
		} else {
			// 小對象分配
		}
	} else {
		// 大對象分配
	}

	publicationBarrier()
	mp.mallocing = 0
	releasem(mp)

	return x}

從代碼中可以看出 runtime.mallocgc 根據對象的大小執行不同的分配邏輯,根據對象大小將它們分成微對象、小對象和大對象

  • 微對象 (0, 16B) — 先使用微型分配器,再依次嘗試線程緩存、中心緩存和堆分配內存

  • 小對象 [16B, 32KB] — 依次嘗試使用線程緩存、中心緩存和堆分配內存

  • 大對象 (32KB, +∞) — 直接在堆上分配內存

go語言垃圾回收機制是什么樣的

小分配

對于小于 32kb 的小分配,Go 會嘗試從 mcache 的本地緩存中獲取內存,該緩存處理一個跨度列表 (32kb 的內存塊) mspan

go語言垃圾回收機制是什么樣的

每個線程 M 都分配給一個處理器 P,一次最多處理一個 goroutine。在分配內存時,當前的 goroutine 將使用其當前的本地緩存 P 來查找 span 列表中第一個可用的空閑對象

大分配

Go 不使用本地緩存管理大型分配。這些大于 32kb 的分配被四舍五入到頁面大小,頁面直接分配到堆中

go語言垃圾回收機制是什么樣的

二、垃圾回收

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

垃回收器與 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 三色標記法

三色標記算法將程序中的對象分成白色、黑色和灰色三類:

  • 白色對象 — 潛在的垃圾,其內存可能會被垃圾收集器回收

  • 黑色對象 — 活躍的對象,包括不存在任何引用外部指針的對象以及從根對象可達的對象

  • 灰色對象 — 活躍的對象,因為存在指向白色對象的外部指針,垃圾收集器會掃描這些對象的子對象

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

  • 從灰色對象的集合中選擇一個灰色對象并將其標記成黑色

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

  • 重復上述兩個步驟直到對象圖中不存在灰色對象

go語言垃圾回收機制是什么樣的

關于go語言垃圾回收機制是什么樣的就分享到這里了,希望以上內容可以對大家有一定的參考價值,可以學以致用。如果喜歡本篇文章,不妨把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

河北区| 曲水县| 南阳市| 报价| 垣曲县| 龙胜| 雷山县| 安阳市| 安义县| 青田县| 乌兰县| 钦州市| 文安县| 堆龙德庆县| 绥棱县| 科技| 嫩江县| 沙田区| 松江区| 筠连县| 翁牛特旗| 资源县| 清水县| 嫩江县| 铜鼓县| 梁山县| 广东省| 淅川县| 黔江区| 昌乐县| 拉孜县| 大足县| 嵊泗县| 中阳县| 工布江达县| 民勤县| 亳州市| 常熟市| 林芝县| 蛟河市| 永川市|