真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

go語(yǔ)言垃圾回收機(jī)制是什么樣的

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

創(chuàng)新互聯(lián)公司成立與2013年,先為曹縣等服務(wù)建站,曹縣等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為曹縣企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問(wèn)題。

go語(yǔ)言有垃圾回收。Go語(yǔ)言自帶垃圾回收機(jī)制(GC);GC通過(guò)獨(dú)立的進(jìn)程執(zhí)行,它會(huì)搜索不再使用的變量,并將其釋放。在計(jì)算中。內(nèi)存空間包含兩個(gè)重要的區(qū)域:棧區(qū) (Stack) 和堆區(qū) (Heap);棧區(qū)一般存儲(chǔ)了函數(shù)調(diào)用的參數(shù)、返回值以及局部變量,不會(huì)產(chǎn)生內(nèi)存碎片,由編譯器管理,無(wú)需開(kāi)發(fā)者管理;而堆區(qū)會(huì)產(chǎn)生內(nèi)存碎片,在Go語(yǔ)言中堆區(qū)的對(duì)象由內(nèi)存分配器分配并由垃圾收集器回收。

Go語(yǔ)言自帶垃圾回收機(jī)制(GC)。GC 通過(guò)獨(dú)立的進(jìn)程執(zhí)行,它會(huì)搜索不再使用的變量,并將其釋放。需要注意的是,GC 在運(yùn)行時(shí)會(huì)占用機(jī)器資源。

Go 語(yǔ)言中的垃圾回收機(jī)制 GC 詳解

在計(jì)算機(jī)科學(xué)中,垃圾回收 (Garbage Collection 簡(jiǎn)稱 GC) 是一種自動(dòng)管理內(nèi)存的機(jī)制,垃圾回收器會(huì)去嘗試回收程序不再使用的對(duì)象及占用的內(nèi)存

程序員受益于 GC,無(wú)需操心、也不再需要對(duì)內(nèi)存進(jìn)行手動(dòng)的申請(qǐng)和釋放操作,GC 在程序運(yùn)行時(shí)自動(dòng)釋放殘留的內(nèi)存
GC 對(duì)程序員幾乎不可見(jiàn),僅在程序需要進(jìn)行特殊優(yōu)化時(shí),通過(guò)提供可調(diào)控的 API,對(duì) GC 的運(yùn)行時(shí)機(jī)、運(yùn)行開(kāi)銷進(jìn)行把控的時(shí)候才得以現(xiàn)身

在計(jì)算中,內(nèi)存空間包含兩個(gè)重要的區(qū)域:棧區(qū) (Stack) 和堆區(qū) (Heap);棧區(qū)一般存儲(chǔ)了函數(shù)調(diào)用的參數(shù)、返回值以及局部變量,不會(huì)產(chǎn)生內(nèi)存碎片,由編譯器管理,無(wú)需開(kāi)發(fā)者管理;而堆區(qū)會(huì)產(chǎn)生內(nèi)存碎片,在 Go 語(yǔ)言中堆區(qū)的對(duì)象由內(nèi)存分配器分配并由垃圾收集器回收?!鞠嚓P(guān)推薦:Go視頻教程、編程教學(xué)】

通常,垃圾回收器的執(zhí)行過(guò)程劃分為兩個(gè)半獨(dú)立的組件:

  • 用戶程序 (Mutator):用戶態(tài)代碼,對(duì)于 GC 而言,用戶態(tài)代碼僅僅只是在修改對(duì)象之間的引用關(guān)系

  • 收集器 (Colletor):負(fù)責(zé)執(zhí)行垃圾回收的代碼

一、內(nèi)存管理和分配

當(dāng)內(nèi)存不再使用時(shí),Go 內(nèi)存管理由其標(biāo)準(zhǔn)庫(kù)自動(dòng)執(zhí)行,即從內(nèi)存分配到 Go 集合。內(nèi)存管理一般包含三個(gè)不同的組件,分別是用戶程序 (Mutator)、分配器 (Allocator) 和收集器 (Collector),當(dāng)用戶程序申請(qǐng)內(nèi)存時(shí),它會(huì)通過(guò)內(nèi)存分配器申請(qǐng)新內(nèi)存,而分配器會(huì)負(fù)責(zé)從堆中初始化相應(yīng)的內(nèi)存區(qū)域

go語(yǔ)言垃圾回收機(jī)制是什么樣的

1.1 內(nèi)存分配器的分配方法

在編程語(yǔ)言中,內(nèi)存分配器一般有兩種分配方法:

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

  • 空閑鏈表分配器 (Free-List Allocator)

線性分配器

線性分配 (Bump Allocator) 是一種高效的內(nèi)存分配方法,但是有較大的局限性。當(dāng)用戶使用線性分配器時(shí),只需要在內(nèi)存中維護(hù)一個(gè)指向內(nèi)存特定位置的指針,如果用戶程序向分配器申請(qǐng)內(nèi)存,分配器只需要檢查剩余的空閑內(nèi)存、返回分配的內(nèi)存區(qū)域并修改指針在內(nèi)存中的位置;

雖然線性分配器有較快的執(zhí)行速度以及較低的實(shí)現(xiàn)復(fù)雜度,但線性分配器無(wú)法在內(nèi)存釋放后重用內(nèi)存。如下圖,如果已經(jīng)分配的內(nèi)存被回收,線性分配器無(wú)法重新利用紅色的內(nèi)存

go語(yǔ)言垃圾回收機(jī)制是什么樣的

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

  • 標(biāo)記壓縮 (Mark-Compact)

  • 復(fù)制回收 (Copying GC)

  • 分代回收 (Generational GC)

以上算法可以通過(guò)拷貝的方式整理存活對(duì)象的碎片,將空閑內(nèi)存定期合并,這樣就能利用線性分配器的效率提升內(nèi)存分配器的性能了

空閑鏈表分配器

空閑鏈表分配器 (Free-List Allocator) 可以重用已經(jīng)被釋放的內(nèi)存,它在內(nèi)部會(huì)維護(hù)一個(gè)類似鏈表的數(shù)據(jù)結(jié)構(gòu)。當(dāng)用戶程序申請(qǐng)內(nèi)存時(shí),空閑鏈表分配器會(huì)依次遍歷空閑的內(nèi)存塊,找到足夠大的內(nèi)存,然后申請(qǐng)新的資源并修改鏈表

go語(yǔ)言垃圾回收機(jī)制是什么樣的

空閑鏈表分配器常見(jiàn)有四種策略:

  • 首次適應(yīng) (First-Fit) — 從鏈表頭開(kāi)始遍歷,選擇第一個(gè)大小大于申請(qǐng)內(nèi)存的內(nèi)存塊

  • 循環(huán)首次適應(yīng) (Next-Fit) — 從上次遍歷的結(jié)束位置開(kāi)始遍歷,選擇第一個(gè)大小大于申請(qǐng)內(nèi)存的內(nèi)存塊

  • 最優(yōu)適應(yīng) (Best-Fit) — 從鏈表頭遍歷整個(gè)鏈表,選擇最合適的內(nèi)存塊

  • 隔離適應(yīng) (Segregated-Fit) — 將內(nèi)存分割成多個(gè)鏈表,每個(gè)鏈表中的內(nèi)存塊大小相同,申請(qǐng)內(nèi)存時(shí)先找到滿足條件的鏈表,再?gòu)逆湵碇羞x擇合適的內(nèi)存塊

其中第四中策略與 Go 語(yǔ)言中使用的內(nèi)存分配策略相似

go語(yǔ)言垃圾回收機(jī)制是什么樣的

該策略會(huì)將內(nèi)存分割成由 4、8、16、32 字節(jié)的內(nèi)存塊組成的鏈表,當(dāng)我們向內(nèi)存分配器申請(qǐng) 8 字節(jié)的內(nèi)存時(shí),它會(huì)在上圖中找到滿足條件的空閑內(nèi)存塊并返回。隔離適應(yīng)的分配策略減少了需要遍歷的內(nèi)存塊數(shù)量,提高了內(nèi)存分配的效率

1.2 Go 中的內(nèi)存分配

一張圖展示內(nèi)存分配組成:

go語(yǔ)言垃圾回收機(jī)制是什么樣的

在 Go 語(yǔ)言中,堆上的所有對(duì)象都會(huì)通過(guò)調(diào)用 runtime.newobject 函數(shù)分配內(nèi)存,該函數(shù)會(huì)調(diào)用 runtime.mallocgc 分配指定大小的內(nèi)存空間,這也是用戶程序向堆上申請(qǐng)內(nèi)存空間的必經(jīng)函數(shù)

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 {
			// 微對(duì)象分配
		} else {
			// 小對(duì)象分配
		}
	} else {
		// 大對(duì)象分配
	}

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

	return x}

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

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

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

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

go語(yǔ)言垃圾回收機(jī)制是什么樣的

小分配

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

go語(yǔ)言垃圾回收機(jī)制是什么樣的

每個(gè)線程 M 都分配給一個(gè)處理器 P,一次最多處理一個(gè) goroutine。在分配內(nèi)存時(shí),當(dāng)前的 goroutine 將使用其當(dāng)前的本地緩存 P 來(lái)查找 span 列表中第一個(gè)可用的空閑對(duì)象

大分配

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

go語(yǔ)言垃圾回收機(jī)制是什么樣的

二、垃圾回收

在 Go 語(yǔ)言中,垃圾回收器實(shí)現(xiàn)的算法是一個(gè)并發(fā)的三色標(biāo)記和掃描收集器

垃回收器與 Go 程序同時(shí)運(yùn)行,因此需要通過(guò)一種寫屏障算法來(lái)檢測(cè)內(nèi)存中的潛在變化。啟動(dòng)寫屏障的唯一條件是在短時(shí)間內(nèi)停止程序,即 “Stop the World”

go語(yǔ)言垃圾回收機(jī)制是什么樣的

寫屏障的目的是允許收集器在收集期間保持堆上的數(shù)據(jù)完整性

2.1 實(shí)現(xiàn)原理

Go 語(yǔ)言的垃圾收集可以分成清除終止、標(biāo)記、標(biāo)記終止和清除四個(gè)不同的階段,其中兩個(gè)階段會(huì)產(chǎn)生 Stop The World (STW)

go語(yǔ)言垃圾回收機(jī)制是什么樣的

清除終止階段

  • 暫停程序,所有的處理器在這時(shí)會(huì)進(jìn)入安全點(diǎn)(Safe point)

  • 如果當(dāng)前垃圾收集循環(huán)是強(qiáng)制觸發(fā)的,我們還需要處理還未被清理的內(nèi)存管理單元

標(biāo)記階段 (STW)

  • 將狀態(tài)切換至 _GCmark、開(kāi)啟寫屏障、用戶程序協(xié)助(Mutator Assists)并將根對(duì)象入隊(duì)

  • 恢復(fù)執(zhí)行程序,標(biāo)記進(jìn)程和用于協(xié)助的用戶程序會(huì)開(kāi)始并發(fā)標(biāo)記內(nèi)存中的對(duì)象,寫屏障會(huì)將被覆蓋的指針和新指針都標(biāo)記成灰色,而所有新創(chuàng)建的對(duì)象都會(huì)被直接標(biāo)記成黑色

  • 開(kāi)始掃描根對(duì)象,包括所有 Goroutine 的棧、全局對(duì)象以及不在堆中的運(yùn)行時(shí)數(shù)據(jù)結(jié)構(gòu),掃描 Goroutine 棧期間會(huì)暫停當(dāng)前處理器

  • 依次處理灰色隊(duì)列中的對(duì)象,將對(duì)象標(biāo)記成黑色并將它們指向的對(duì)象標(biāo)記成灰色

  • 使用分布式的終止算法檢查剩余的工作,發(fā)現(xiàn)標(biāo)記階段完成后進(jìn)入標(biāo)記終止階段

標(biāo)記終止階段 (STW)

  • 暫停程序、將狀態(tài)切換至 _GCmarktermination 并關(guān)閉輔助標(biāo)記的用戶程序

  • 清理處理器上的線程緩存

清理階段

  • 將狀態(tài)切換至 _GCoff 開(kāi)始清理階段,初始化清理狀態(tài)并關(guān)閉寫屏障

  • 恢復(fù)用戶程序,所有新創(chuàng)建的對(duì)象會(huì)標(biāo)記成白色

  • 后臺(tái)并發(fā)清理所有的內(nèi)存管理單元,當(dāng) Goroutine 申請(qǐng)新的內(nèi)存管理單元時(shí)就會(huì)觸發(fā)清理

2.2 三色標(biāo)記法

三色標(biāo)記算法將程序中的對(duì)象分成白色、黑色和灰色三類:

  • 白色對(duì)象 — 潛在的垃圾,其內(nèi)存可能會(huì)被垃圾收集器回收

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

  • 灰色對(duì)象 — 活躍的對(duì)象,因?yàn)榇嬖谥赶虬咨珜?duì)象的外部指針,垃圾收集器會(huì)掃描這些對(duì)象的子對(duì)象

三色標(biāo)記垃圾收集器的工作原理很簡(jiǎn)單,可以將其歸納成以下幾個(gè)步驟:

  • 從灰色對(duì)象的集合中選擇一個(gè)灰色對(duì)象并將其標(biāo)記成黑色

  • 將黑色對(duì)象指向的所有對(duì)象都標(biāo)記成灰色,保證該對(duì)象和被該對(duì)象引用的對(duì)象都不會(huì)被回收

  • 重復(fù)上述兩個(gè)步驟直到對(duì)象圖中不存在灰色對(duì)象

go語(yǔ)言垃圾回收機(jī)制是什么樣的

關(guān)于go語(yǔ)言垃圾回收機(jī)制是什么樣的就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的參考價(jià)值,可以學(xué)以致用。如果喜歡本篇文章,不妨把它分享出去讓更多的人看到。


分享文章:go語(yǔ)言垃圾回收機(jī)制是什么樣的
URL標(biāo)題:http://weahome.cn/article/pppcdh.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部