成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Go GC 怎么標(biāo)記內(nèi)存?顏色是什么含義?圖解三色標(biāo)記法

開發(fā) 前端
Go GC 的作用是回收不再使用的內(nèi)存。實(shí)現(xiàn)的算法是并發(fā)的三色標(biāo)記和清除回收法。本中文,我們研究三色標(biāo)記法,以及各個(gè)顏色的不同用處。

Go GC 怎么標(biāo)記內(nèi)存?顏色是什么含義?圖解三色標(biāo)記法
Illustration created for “A Journey With Go”, made from the original Go Gopher, created by Renee French

本文基于 Go 1.13。關(guān)于內(nèi)存管理的概念的討論在我的文章 Go 中的內(nèi)存管理和分配[1] 中有詳細(xì)的解釋。

Go GC 的作用是回收不再使用的內(nèi)存。實(shí)現(xiàn)的算法是并發(fā)的三色標(biāo)記和清除回收法。本中文,我們研究三色標(biāo)記法,以及各個(gè)顏色的不同用處。

你可以在 Ken Fox 的 解讀垃圾回收算法[2] 中了解更多關(guān)于不同垃圾回收機(jī)制的信息。

標(biāo)記階段

這個(gè)階段瀏覽內(nèi)存來了解哪些塊兒是在被我們的代碼使用和哪些塊兒應(yīng)該被回收。

然而,因?yàn)?GC 和我們的 Go 程序并行,GC 掃描期間內(nèi)存中某些對(duì)象的狀態(tài)可能被改變,所以需要一個(gè)檢測(cè)這種可能的變化的方法。為了解決這個(gè)潛在的問題,實(shí)現(xiàn)了 寫屏障[3] 算法,GC 可以追蹤到任何的指針修改。使寫屏障生效的唯一條件是短暫終止程序,又名 “Stop the World”。

 

Go GC 怎么標(biāo)記內(nèi)存?顏色是什么含義?圖解三色標(biāo)記法

在進(jìn)程啟動(dòng)時(shí),Go 也在每個(gè) processor 起了一個(gè)標(biāo)記 worker 來輔助標(biāo)記內(nèi)存。

然后,當(dāng) root 被加入到處理隊(duì)列中后,標(biāo)記階段就開始遍歷和用顏色標(biāo)記內(nèi)存。

為了了解在標(biāo)記階段的每一步,我們來看一個(gè)簡(jiǎn)單的程序示例:

  1. type struct1 struct { 
  2.  a, b int64 
  3.  c, d float64 
  4.  e *struct2 
  5.  
  6. type struct2 struct { 
  7.  f, g int64 
  8.  h, i float64 
  9.  
  10. func main() { 
  11.  s1 := allocStruct1() 
  12.  s2 := allocStruct2() 
  13.  
  14.  func () { 
  15.   _ = allocStruct2() 
  16.  }() 
  17.  
  18.  runtime.GC() 
  19.  
  20.  fmt.Printf("s1 = %X, s2 = %X\n", &s1, &s2) 
  21.  
  22. //go:noinline 
  23. func allocStruct1() *struct1 { 
  24.  return &struct1{ 
  25.   e: allocStruct2(), 
  26.  } 
  27.  
  28. //go:noinline 
  29. func allocStruct2() *struct2 { 
  30.  return &struct2{} 

struct2 不包含指針,因此它被儲(chǔ)存在一個(gè)專門存放不被其他對(duì)象引用的對(duì)象的 span 中。

 

Go GC 怎么標(biāo)記內(nèi)存?顏色是什么含義?圖解三色標(biāo)記法

不包含指針的結(jié)構(gòu)體儲(chǔ)存在專有的 span 中

這減少了 GC 的工作,因?yàn)闃?biāo)記內(nèi)存時(shí)不需要掃描這個(gè) span。

分配工作結(jié)束后,我們的程序強(qiáng)迫 GC 重復(fù)前面的步驟。下面是流程圖:

 

Go GC 怎么標(biāo)記內(nèi)存?顏色是什么含義?圖解三色標(biāo)記法

掃描內(nèi)存

GC 從棧開始,遞歸地順著指針找指針指向的對(duì)象,遍歷內(nèi)存。掃描到被標(biāo)記為 no scan 的 span 時(shí),停止掃描。然而,這個(gè)工作是在多個(gè)協(xié)程中完成的,每個(gè)指針被加入到一個(gè) work pool 中的隊(duì)列。然后,后臺(tái)運(yùn)行的標(biāo)記 worker 從這個(gè) work pool 中拿到前面出列的 work,掃描這個(gè)對(duì)象然后把在這個(gè)對(duì)象里找到的指針加入到隊(duì)列。

 

Go GC 怎么標(biāo)記內(nèi)存?顏色是什么含義?圖解三色標(biāo)記法
garbage collector work pool

顏色標(biāo)記

worker 需要一種記錄哪些內(nèi)存需要掃描的方法。GC 使用一種 三色標(biāo)記算法[4],工作流程如下:

  • 開始時(shí),所有對(duì)象都被認(rèn)為是白色
  • root 對(duì)象(棧,堆,全局變量)被標(biāo)記為灰色

這個(gè)初始步驟完成后,GC 會(huì):

  • 選擇一個(gè)灰色的對(duì)象,標(biāo)記為黑色
  • 追蹤這個(gè)對(duì)象的所有指針,把所有引用的對(duì)象標(biāo)記為灰色

然后,GC 重復(fù)以上兩步,直到?jīng)]有對(duì)象可被標(biāo)記。在這一時(shí)刻,對(duì)象非黑即白,沒有灰色。白色的對(duì)象表示沒有其他對(duì)象引用,可以被回收。

下面是前面例子的圖示:

 

Go GC 怎么標(biāo)記內(nèi)存?顏色是什么含義?圖解三色標(biāo)記法

初始狀態(tài)下,所有的對(duì)象被認(rèn)為是白色的。然后,遍歷到的且被其他對(duì)象引用的對(duì)象,被標(biāo)記為灰色。如果一個(gè)對(duì)象在被標(biāo)記為 no scan 的 span 中,因?yàn)樗恍枰粧呙瑁钥梢詷?biāo)記為黑色。

 

Go GC 怎么標(biāo)記內(nèi)存?顏色是什么含義?圖解三色標(biāo)記法

現(xiàn)在灰色的對(duì)象被加入到掃描隊(duì)列并被標(biāo)記為黑色:

 

Go GC 怎么標(biāo)記內(nèi)存?顏色是什么含義?圖解三色標(biāo)記法

對(duì)加入到掃描隊(duì)列的所有對(duì)象重復(fù)做相同的操作,直到?jīng)]有對(duì)象需要被處理:

 

Go GC 怎么標(biāo)記內(nèi)存?顏色是什么含義?圖解三色標(biāo)記法

處理結(jié)束時(shí),黑色對(duì)象表示內(nèi)存中在使用的對(duì)象,白色對(duì)象是要被回收的對(duì)象。我們可以看到,由于 struct2 的實(shí)例是在一個(gè)匿名函數(shù)中創(chuàng)建的且不再存在于棧上,因此它是白色的且可以被回收。

歸功于每一個(gè) span 中的名為 gcmarkBits 的 bitmap 屬性,三色被原生地實(shí)現(xiàn)了,bitmap 對(duì) scan 中相應(yīng)的 bit 設(shè)為 1 來追蹤 scan。

 

Go GC 怎么標(biāo)記內(nèi)存?顏色是什么含義?圖解三色標(biāo)記法

我們可以看到,黑色和灰色表示的意義相同。處理的不同之處在于,標(biāo)記為灰色時(shí)是把對(duì)象加入到掃描隊(duì)列,而標(biāo)記為黑色時(shí),不再掃描。

GC 最終 STW,清除每一次寫屏障對(duì) work pool 做的改變,繼續(xù)后續(xù)的標(biāo)記。

你可以在我的文章 Go GC 怎樣監(jiān)控你的應(yīng)用[5] 中找到關(guān)于并發(fā)處理和 GC 的標(biāo)記階段更詳細(xì)的描述。

runtime 分析器

Go 提供的工具使我們可以對(duì)每一步進(jìn)行可視化,觀察 GC 在我們的程序中的影響。開啟 tracing 運(yùn)行我們的代碼,可以看到前面所有步驟的一個(gè)概覽。下面是追蹤結(jié)果:

 

Go GC 怎么標(biāo)記內(nèi)存?顏色是什么含義?圖解三色標(biāo)記法
traces of the garbage collector

標(biāo)記 worker 的生命周期也可以在追蹤結(jié)果中以協(xié)程等級(jí)可視化。下面是在啟動(dòng)之前先在后臺(tái)等待標(biāo)記內(nèi)存的 Goroutine #33 的例子。

 

Go GC 怎么標(biāo)記內(nèi)存?顏色是什么含義?圖解三色標(biāo)記法
marking worker

 

責(zé)任編輯:未麗燕 來源: Go語言中文網(wǎng)
相關(guān)推薦

2021-08-06 11:46:46

Go三色標(biāo)記法

2023-01-08 13:46:49

2021-08-16 10:35:52

JVM標(biāo)記法屏障

2023-06-19 07:12:51

JVM三色標(biāo)記

2023-03-15 09:49:00

CMSG1三色標(biāo)

2025-01-06 08:22:41

2022-08-15 08:01:00

三色標(biāo)記JVM算法

2024-05-23 12:40:06

2019-08-19 12:50:00

Go垃圾回收前端

2022-01-20 10:34:49

JVM垃圾回收算法

2023-07-29 15:03:29

2009-06-24 09:19:56

JSF標(biāo)記JSTL標(biāo)記

2022-06-06 11:29:16

軟件包安裝開發(fā)包

2010-07-06 16:26:33

2009-07-03 09:08:23

JSP標(biāo)記學(xué)習(xí)筆記

2009-07-03 09:08:23

JSP標(biāo)記學(xué)習(xí)筆記

2013-03-25 09:25:48

OpenStack公有云Nova

2020-06-01 20:08:47

垃圾G1回收器

2021-09-29 09:24:21

GCGo STW

2010-02-23 13:36:42

WCF DataCon
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 久久久久久久久中文字幕 | 久久精品国产一区二区电影 | 日韩在线精品 | 啪啪综合网 | 久久久久久久久久影视 | 日韩午夜精品 | 99re在线视频 | 影音先锋欧美资源 | 国产午夜精品一区二区三区嫩草 | 久久人体视频 | 蜜桃精品噜噜噜成人av | 久久精品69 | 亚洲欧美一区二区三区国产精品 | 成人精品久久久 | 一区二区成人 | 欧州一区二区三区 | 国产99久久久国产精品下药 | 欧美性猛交一区二区三区精品 | 亚洲福利免费 | 色吊丝在线 | 天天爽网站 | 欧美日韩黄色一级片 | 黄色一级视频 | 成人国产a | 9191av| 欧美视频三级 | 久久久久国产 | 午夜一区| 91精品国产综合久久香蕉922 | 欧美综合国产精品久久丁香 | 伊人网在线播放 | 黄色电影在线免费观看 | 亚洲欧美中文日韩在线v日本 | 男人的天堂在线视频 | 国产精品久久久久久av公交车 | 最近免费日本视频在线 | 农村妇女毛片精品久久久 | 黄色三级在线播放 | 亚洲一区二区三区在线观看免费 | 亚洲精品高清视频 | 特级生活片|