成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

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

Go GC 簡介

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ù)解決您的所有建站問題。

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

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

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

了解 GC 的好地方,可以從 Richard Jones 的 gchandbook.org 開始。

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

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

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

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

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

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

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

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

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

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

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

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

? ?e.?? 由于 GC work 分散在本地緩存中,因此 GC 使用 分布式終止算法 來檢測何時(shí)不再有根標(biāo)記作業(yè)或灰色對象(參見 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)在開始,新分配的對象是白色的,如有必要,在使用 spans 前 allocating 清除 spans 。

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

5. 當(dāng)分配足夠時(shí),重復(fù)上面 1 開始的步驟,參見下面關(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 簡單地逐個(gè)清除 span 。

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

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

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

有一種情況,這可能是不夠的:如果 goroutine 清除并釋放兩個(gè)不相鄰的 單頁span 到堆中,那么它將分配一個(gè)新的 雙頁span ,但是仍然可以有其他 單頁未清除的span ,可以組合成 雙頁的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 顯式釋放對象或設(shè)置 finalizer 時(shí),goroutine 確保 span 已經(jīng)清除(通過清除或者等待并發(fā)清除完成)。

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

當(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)存量)。

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

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

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

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

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

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

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

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

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

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

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

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

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

gcStart 是 Go 語言三種條件觸發(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ā)的問題 和 GMP、mcache 一樣設(shè)計(jì),減少鎖競爭

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

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

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

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

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

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

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

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

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

go的垃圾回收算法

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

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

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

標(biāo)記清除方法

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

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

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

網(wǎng)頁名稱:go語言gc狀態(tài)收集 go的gc對比java 的gc
路徑分享:http://jinyejixie.com/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)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)
页游| 宿松县| 铜山县| 宁德市| 德格县| 临西县| 安溪县| 中山市| 新竹县| 松桃| 祥云县| 裕民县| 孟村| 红原县| 合江县| 郧西县| 灵宝市| 云霄县| 章丘市| 贡山| 镇雄县| 柳州市| 涟水县| 米易县| 绍兴县| 古浪县| 宝山区| 旬阳县| 依安县| 娄底市| 永仁县| 赞皇县| 多伦县| 项城市| 恩平市| 乌什县| 铜陵市| 井冈山市| 永新县| 敖汉旗| 永平县|