中文字幕日韩精品一区二区免费_精品一区二区三区国产精品无卡在_国精品无码专区一区二区三区_国产αv三级中文在线

go語(yǔ)言gc狀態(tài)收集 go的gc對(duì)比java 的gc

Go GC 簡(jiǎn)介

GC 與 mutator 線程并發(fā)運(yùn)行,允許多個(gè) GC 線程并行運(yùn)行

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

GC 是一個(gè)使用寫屏障的并發(fā)標(biāo)記和清除。

GC 是非分代的,非緊湊的。

Allocation 是按照大小隔離每個(gè) P 分配的區(qū)域來(lái)完成的,以在消除常見(jiàn)情況下的鎖的同時(shí),最小化碎片。

了解 GC 的好地方,可以從 Richard Jones 的 gchandbook.org 開(kāi)始。

1. GC 執(zhí)行清除終止

? a. Stop the world ,這將導(dǎo)致所有 P 達(dá)到 GC 安全點(diǎn)。

? b. 清除任何未清除過(guò)的 spans ,只有在預(yù)期時(shí)間之前強(qiáng)制執(zhí)行此 GC 周期時(shí),才會(huì)有未清除的 span 。

2. GC 執(zhí)行標(biāo)記階段

? a.?? 準(zhǔn)備標(biāo)記階段,將 gcphase 設(shè)置為 _GCmark (從 _GCoff 開(kāi)始),啟用寫屏障,啟用 mutator assist ,并對(duì)根標(biāo)記作業(yè)進(jìn)行排隊(duì)。

在所有 P 都啟用寫屏障之前,不會(huì)掃描任何對(duì)象,這是使用 STW 完成的。

? ?b. Start the world ,從現(xiàn)在開(kāi)始,GC 工作由調(diào)度器啟動(dòng)的 標(biāo)記worker 和作 為 allocation 的一部分執(zhí)行的 assists 來(lái)完成。

寫屏障將覆寫的指針和任何指針寫的新指針值都著色。

新分配的對(duì)象立即被標(biāo)記為黑色。

? c.?? GC 執(zhí)行根標(biāo)記作業(yè)。包括: 掃描所有棧 , 著色所有全局變量 ,以及 著色堆外運(yùn)行時(shí)數(shù)據(jù)結(jié)構(gòu)中的任何堆指針 。

掃描棧會(huì)停止goroutine,對(duì)goroutine棧中找到的任何指針進(jìn)行著色,然后恢復(fù)goroutine。

? ? d.?? GC 耗盡灰色對(duì)象的工作隊(duì)列,將每個(gè) 灰色 對(duì)象掃描為 黑色 ,并對(duì)在該對(duì)象中找到的所有指針進(jìn)行著色(反過(guò)來(lái)可能會(huì)將這些指針添加到工作隊(duì)列中)。

? ?e.?? 由于 GC work 分散在本地緩存中,因此 GC 使用 分布式終止算法 來(lái)檢測(cè)何時(shí)不再有根標(biāo)記作業(yè)或灰色對(duì)象(參見(jiàn) gcMarkDone 函數(shù))。

此時(shí),GC 狀態(tài)轉(zhuǎn)換到標(biāo)記終止( gcMarkTermination )。

3. GC 執(zhí)行標(biāo)記終止 gcMarkTermination

? a. Stop the world

? b. 將 gcphase 設(shè)置為 _GCmarktermination ,并禁用 workers 和 assists。

? c. 進(jìn)行內(nèi)務(wù)整理,如 flushing mcaches

4. GC 執(zhí)行清除階段

? ?a. 準(zhǔn)備清除階段,將 gcphase 設(shè)置為 _GCoff ,設(shè)置清除狀態(tài)并禁用寫屏障。

? b. Start the world ,從現(xiàn)在開(kāi)始,新分配的對(duì)象是白色的,如有必要,在使用 spans 前 allocating 清除 spans 。

? ?c. GC 在后臺(tái)進(jìn)行 并發(fā)清除 并響應(yīng) allocation ,見(jiàn)下面的描述。

5. 當(dāng)分配足夠時(shí),重復(fù)上面 1 開(kāi)始的步驟,參見(jiàn)下面關(guān)于 GC rate 的討論。

清除階段與正常程序執(zhí)行并發(fā)進(jìn)行。

在后臺(tái) goroutine 中,堆被惰性(當(dāng) goroutine 需要另一個(gè) span 時(shí))且并發(fā)地逐個(gè) span 掃描(這有助于不是 CPU bound 的程序)。

在 STW 標(biāo)記終止 的結(jié)尾,所有的 span 都被標(biāo)記為 需要清除 。

后臺(tái)清除器 goroutine 簡(jiǎn)單地逐個(gè)清除 span 。

為了避免在存在未清除的 span 時(shí)請(qǐng)求更多的 OS內(nèi)存 ,當(dāng) goroutine 需要另一個(gè) span 時(shí),它首先嘗試通過(guò)清除來(lái)回收這些內(nèi)存。

當(dāng) goroutine 需要分配一個(gè)新的 小對(duì)象span 時(shí),它會(huì)清除相同大小的小對(duì)象 span ,直到釋放至少一個(gè)對(duì)象為止。

當(dāng) goroutine 需要從堆中分配 大對(duì)象span 時(shí),它會(huì)清除 span ,直到將至少那么多頁(yè)面釋放到堆中。

有一種情況,這可能是不夠的:如果 goroutine 清除并釋放兩個(gè)不相鄰的 單頁(yè)span 到堆中,那么它將分配一個(gè)新的 雙頁(yè)span ,但是仍然可以有其他 單頁(yè)未清除的span ,可以組合成 雙頁(yè)的span 。

確保在未清除的 span 上不進(jìn)行任何操作(這會(huì)破壞 GC 位圖中的標(biāo)記位)至關(guān)重要。

在 GC 期間,所有 mcache 都被刷新到 中央緩存 中,因此它們是空的。

當(dāng)一個(gè) goroutine 抓取一個(gè)新的 span 到 mcache 時(shí), goroutine 會(huì)清除 mcache 。

當(dāng) goroutine 顯式釋放對(duì)象或設(shè)置 finalizer 時(shí),goroutine 確保 span 已經(jīng)清除(通過(guò)清除或者等待并發(fā)清除完成)。

finalizer goroutine 僅在所有 span 已經(jīng)清除時(shí)才開(kāi)始。

當(dāng)下一次 GC 啟動(dòng)時(shí),它將清除所有尚未清除的 span (如果有的話)。

下一次 GC 是在我們分配了與已經(jīng)使用的內(nèi)存成正比的額外內(nèi)存量之后。

該比例由 GOGC 環(huán)境變量控制(默認(rèn)為 100 )。

如果 GOGC=100 ,而我們使用的是 4M ,那么當(dāng)達(dá)到 8M 時(shí),我們將再次進(jìn)行 GC(此標(biāo)記在 next_gc 變量中被跟蹤)。

獲取 GOGC :

這使得 GC成本 與 allocation 成本 成線性比例。

調(diào)整 GOGC 只會(huì)改變線性常量(以及使用的額外內(nèi)存量)。

為了防止在掃描大型對(duì)象時(shí)出現(xiàn)長(zhǎng)時(shí)間的暫停,并提高并行性,垃圾收集器將大于 maxObletBytes 的對(duì)象的掃描作業(yè)分解為最多 maxObletBytes 的 oblets 。

當(dāng)掃描遇到大對(duì)象時(shí),它只掃描第一個(gè) oblet ,并將其余 oblets 作為新的掃描作業(yè)排隊(duì)。

Go 語(yǔ)言三色標(biāo)記掃描對(duì)象是 DFS 還是 BFS?

最近在看左神新書 《Go 語(yǔ)言設(shè)計(jì)與實(shí)現(xiàn)》的垃圾收集器時(shí)產(chǎn)生一個(gè)疑惑,花了點(diǎn)時(shí)間搞清楚了記錄一下。

Go 語(yǔ)言垃圾回收的實(shí)現(xiàn)使用了標(biāo)記清除算法,將對(duì)象的狀態(tài)抽象成黑色(活躍對(duì)象)、灰色(活躍對(duì)象中間狀態(tài))、白色(潛在垃圾對(duì)象也是所有對(duì)象的默認(rèn)狀態(tài))三種,注意沒(méi)有具體的字段標(biāo)記顏色。

整個(gè)標(biāo)記過(guò)程就是把白色對(duì)象標(biāo)黑的過(guò)程:

1.首先將 ROOT 根對(duì)象(包括全局變量、goroutine 棧上的對(duì)象等)放入到灰色集合

2.選一個(gè)灰色對(duì)象,標(biāo)成黑色,將所有可達(dá)的子對(duì)象放入到灰色集合

3.重復(fù)2的步驟,直到灰色集合中為空

下圖是書上的插圖,看上去是一個(gè)典型的深度優(yōu)先搜索的算法。

下圖是劉丹冰寫的《Golang 修養(yǎng)之路》的插圖,看上去是一個(gè)典型的廣度優(yōu)先搜索的算法。

我疑惑的點(diǎn)在于這個(gè)標(biāo)記過(guò)程是深度優(yōu)先算法還是廣度優(yōu)先算法,因?yàn)楹芏辔恼虏┛蛯?duì)此都沒(méi)有很清楚的說(shuō)明,作為學(xué)習(xí)者這種細(xì)節(jié)其實(shí)也不影響對(duì)整個(gè) GC 流程的理解,但是這種細(xì)節(jié)我非常喜歡扣:)

對(duì)著書和源碼摸索著大致找到了一個(gè)結(jié)果是深度優(yōu)先。下面看下大致的過(guò)程,源碼基于1.15.2版本:

gcStart 是 Go 語(yǔ)言三種條件觸發(fā) GC 的共同入口

啟動(dòng)后臺(tái)標(biāo)記任務(wù)

為每個(gè)處理器創(chuàng)建用于執(zhí)行后臺(tái)標(biāo)記任務(wù)的 Goroutine

上面休眠的 G 會(huì)在調(diào)度循環(huán)中檢查并喚醒執(zhí)行

執(zhí)行標(biāo)記

gcw 是每個(gè) P 獨(dú)有的所以不用擔(dān)心并發(fā)的問(wèn)題 和 GMP、mcache 一樣設(shè)計(jì),減少鎖競(jìng)爭(zhēng)

嘗試在全局列表中獲取一個(gè)不為空的 buf

這是官方實(shí)現(xiàn)的無(wú)鎖隊(duì)列:)漲見(jiàn)識(shí)了,for 循環(huán)加原子操作實(shí)現(xiàn)棧的 pop

到這里從灰色集合中獲取待掃描的對(duì)象邏輯說(shuō)完了。找到對(duì)象了接著就是 scanobject(b, gcw) 了,里面有兩段邏輯要注意

根據(jù)索引位置找到對(duì)象進(jìn)行標(biāo)色

嘗試存入 gcwork 的緩存中,或全局隊(duì)列中

無(wú)鎖隊(duì)列,for 循環(huán)加原子操作實(shí)現(xiàn)棧的 push

到這里把灰色對(duì)象標(biāo)黑就完成了,又放回灰色集合接著掃下一個(gè)指針。

Go 語(yǔ)言設(shè)計(jì)與實(shí)現(xiàn) 垃圾收集器

Golang三色標(biāo)記+混合寫屏障GC模式全分析

go的垃圾回收算法

從Gov1.12版本開(kāi)始,Go使用了非分代的、并發(fā)的、基于三色標(biāo)記清除的垃圾回收器。

關(guān)于垃圾回收,比較常見(jiàn)的算法有引用計(jì)數(shù)、標(biāo)記清除和分代收集,Golang語(yǔ)言使用的垃圾回收算法是標(biāo)記清除。

Golang語(yǔ)言的標(biāo)記清除垃圾回收算法,為了防止GC掃描時(shí)內(nèi)存變化引起的混亂。那么就需要 STW,即Stop The World。具體在Golang語(yǔ)言中是指,在GC時(shí)先停止所有g(shù)oroutine。再進(jìn)行垃圾回收,等待垃圾回收結(jié)束后再恢復(fù)所有被停止的goroutine。

標(biāo)記清除方法

啟動(dòng)STW,暫停程序的業(yè)務(wù)邏輯,找出不可達(dá)對(duì)象和可達(dá)對(duì)象。

將所有可達(dá)對(duì)象做標(biāo)記,清除未標(biāo)記的對(duì)象。停止STW,程序繼續(xù)執(zhí)行。循環(huán)往復(fù),直到進(jìn)程程序生命周期結(jié)束。因?yàn)镾TW需要暫停程序,為了減少暫停程序的時(shí)間。將清除操作移出 STW執(zhí)行周期,但是優(yōu)化效果不明顯。

所謂三色標(biāo)記,實(shí)際上只是為了方便敘述而抽象出來(lái)的一種說(shuō)法,三色對(duì)應(yīng)垃圾回收過(guò)程中對(duì)象的三種狀態(tài)。白色是對(duì)象未被標(biāo)記,gcmarkBits對(duì)應(yīng)位為0,該對(duì)象將會(huì)在本次GC中被清理。灰色是對(duì)象還在標(biāo)記隊(duì)列中等待被標(biāo)記,黑色是對(duì)象已被標(biāo)記,gcmarkBits對(duì)應(yīng)位為0,該對(duì)象將會(huì)在本次 GC中被回收。

網(wǎng)頁(yè)名稱:go語(yǔ)言gc狀態(tài)收集 go的gc對(duì)比java 的gc
路徑分享:http://m.rwnh.cn/article8/dodoiip.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供動(dòng)態(tài)網(wǎng)站、企業(yè)建站、做網(wǎng)站網(wǎng)站建設(shè)、服務(wù)器托管關(guān)鍵詞優(yōu)化

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)
佳木斯市| 乳源| 措美县| 衡阳市| 卢龙县| 观塘区| 嘉善县| 巩义市| 武乡县| 怀集县| 奉化市| 都昌县| 美姑县| 天全县| 甘南县| 柘城县| 临湘市| 公主岭市| 陕西省| 芜湖市| 房产| 佛教| 揭阳市| 化隆| 综艺| 农安县| 尤溪县| 阳春市| 平江县| 武功县| 喜德县| 宣威市| 井冈山市| 丰原市| 达孜县| 五台县| 内江市| 九江市| 铅山县| 玛曲县| 襄城县|