go gc 分析

1 先翻譯一下runtime 文檔中症歇,關(guān)于gc的內(nèi)容(里面涉及GC日志格式)

···
原文: https://golang.org/pkg/runtime/
翻譯參考: https://colobu.com/2016/07/04/dive-into-go-11/#pprof

···

allocfreetrace: 設(shè)置 allocfreetrace=1 會監(jiān)控每次分配郎笆,但因每次分配和釋放的棧信息(stack trace)

cgocheck: 設(shè)置 cgocheck=0 禁用所有cgo檢查將Go指針傳遞給非Go代碼是否正確。
cgocheck=1 (缺省值) 輕量級檢查忘晤。cgocheck=2 重量級檢查宛蚓。

efence: 設(shè)置 efence=1 導(dǎo)致分配器 allocator將每個對象分配在一個唯一的頁page上,地址不重用设塔。

gccheckmark: 設(shè)置 gccheckmark=1 允許垃圾回收器執(zhí)行并發(fā)mark階段的校驗凄吏。會導(dǎo)致Stop The World。

gcpacertrace: 設(shè)置 gcpacertrace=1 會讓來幾回收器打印出concurrent pacer的內(nèi)部狀態(tài)。

gcshrinkstackoff: 設(shè)置 gcshrinkstackoff=1 則禁止將 goroutines 的椇鄹郑縮小為更小棧图柏。

gcstackbarrieroff: 設(shè)置 gcstackbarrieroff=1 禁用stack barriers,會影響垃圾回收器的重復(fù)搜索棧的功能盖喷。

gcstackbarrierall: 設(shè)置 gcstackbarrierall=1 會為每個棧幀安裝一 stack barriers爆办。

gcstoptheworld: 設(shè)置 gcstoptheworld=1 則禁用并發(fā)垃圾回收,每次回收都會觸發(fā)STW。設(shè)置gcstoptheworld=2則禁用垃圾回收后的concurrent sweeping课梳。

gctrace: 設(shè)置 gctrace=1導(dǎo)致每次垃圾回收器觸發(fā)一行日志距辆,包含內(nèi)存回收的概要信息和暫停的時間。設(shè)置gctrace=2起同樣的效果暮刃,but also repeats each collection跨算。格式如下:

gc # @#s #%: #+#+# ms clock, #+#/#/#+# ms cpu, #->#-># MB, # MB goal, # P

where the fields are as follows:
gc # GC id,每次GC加一
@#s 程序啟動后的時間,單位秒
#% 程序啟動后GC所用的時間比
#+...+# 此次GC所用的wall-clock/CPU時間
#->#-># MB GC開始時的堆大小, GC結(jié)束時的堆大小, 活著的(live)堆大小
# MB goal 總的堆大小
# P CPU使用數(shù)
垃圾回收分為下面的幾個階段:stop-the-world (STW) sweep termination, concurrent
mark and scan, and STW mark termination椭懊。 mark/scan的CPU時間又分為 assist time (GC performed in
line with allocation), background GC time, and idle GC time诸蚕。

垃圾回收的四個階段:
Sweep Termination: 對未清掃的span進(jìn)行清掃, 只有上一輪的GC的清掃工作完成才可以開始新一輪的GC
Mark: 掃描所有根對象, 和根對象可以到達(dá)的所有對象, 標(biāo)記它們不被回收
Mark Termination: 完成標(biāo)記工作, 重新掃描部分根對象(要求STW)
Sweep: 按標(biāo)記結(jié)果清掃span

如果日志后以"(forced)"結(jié)尾,則GC通過runtime.GC()調(diào)用執(zhí)行,此時所有的階段都是STW.

memprofilerate: 設(shè)置 memprofilerate=X 會更新runtime.MemProfileRate的值氧猬。0則禁用這個profie背犯。

invalidptr: 默認(rèn)設(shè)為invalidptr=1, 如果指針被賦予一個無效值,會引起程序的崩潰,設(shè)置該值為0盅抚,會停止該檢查漠魏,
0只能臨時用于查找bug,真正的解決方法是不要把整數(shù)類型的值存在指針變量里面妄均。

sbrk: 設(shè)置 sbrk=1 會使用實驗性的實現(xiàn)替換memory allocator 和 garbage collector柱锹。

scavenge: scavenge=1 允許heap scavenger的debug模式。

scheddetail: 設(shè)置 schedtrace=X 和 scheddetail=1 會導(dǎo)致goroutine調(diào)度器每個X毫秒輸出多行調(diào)度信息丰包。

schedtrace: 設(shè)置 schedtrace=X導(dǎo)致調(diào)度器每個X秒輸出一行調(diào)度器的概要信息禁熏。

2 GC 觸發(fā)時機(jī)

gcTriggerHeap: 當(dāng)前分配的內(nèi)存達(dá)到一定值就觸發(fā)GC
gcTriggerTime: 當(dāng)一定時間沒有執(zhí)行過GC就觸發(fā)GC
gcTriggerCycle: 要求啟動新一輪的GC, 已啟動則跳過, 手動觸發(fā)GC的runtime.GC()會使用這個條件

3 gc 具體的過程

3.1 根對象

在GC的標(biāo)記階段首先需要標(biāo)記的就是"根對象", 從根對象開始可到達(dá)的所有對象都會被認(rèn)為是存活的.
根對象包含了全局變量, 各個G的棧上的變量等, GC會先掃描根對象然后再掃描根對象可到達(dá)的所有對象.

3.2 三色標(biāo)記過程

之前自己整理的 http://www.reibang.com/p/ebf03d9605d0

4 gc 優(yōu)化案例

4.1 減少分配對象數(shù)量(這樣就減少了掃描時間)

鏈接:https://www.zhihu.com/question/21615032/answer/18781477

4.2 一個檢測G 長時間占用CPU時間片,導(dǎo)致GC hang住的排查工具

https://github.com/zhanglvmeng/go-tool-trace-greediest-goroutines

4.3 【已驗證】io.copybuffer 沒傳buffer進(jìn)去邑彪,底層自動創(chuàng)建了多個buffer對象瞧毙,造成內(nèi)存泄漏,頻繁gc寄症。

https://my.oschina.net/u/2950272/blog/1788299

4.4 使用array 替代 map, 減少掃描時間

https://studygolang.com/articles/1720

4.5 多個不同維度的分析

http://guileen.github.io/2016/06/15/how-did-i-optimize-golang-gc/

4.6 減少GC的一些思路

http://www.philo.top/2015/05/29/golangProfilingAndGC2/

4.7 GC排查的步驟

http://xiaorui.cc/2016/03/20/golang%E4%BD%BF%E7%94%A8pprof%E7%9B%91%E6%8E%A7%E6%80%A7%E8%83%BD%E5%8F%8Agc%E8%B0%83%E4%BC%98/

4.8 string 以及[]byte 的GC問題

https://www.520mwx.com/view/35045

5 gc 查看工具

gcvis https://github.com/davecheney/gcvis
參考自 https://colobu.com/2016/07/04/dive-into-go-11/#pprof

6 GC 監(jiān)控

對于線上GC的監(jiān)控升筏,基本上讀取runtime.MemStats結(jié)構(gòu)中的內(nèi)容,然后存儲到時序數(shù)據(jù)庫中。具體有如下兩種獲取方式:

// 方式1
memStats := &runtime.MemStats{}
runtime.ReadMemStats(memStats)

// 方式2 json格式
expvar.Get("memstats").String()

7 scavenger

到目前為止,gctrace給出的最有用的信息就是 the heap scavenger的輸出.

scvg143: inuse: 8, idle: 104, sys: 113, released: 104, consumed: 8 (MB)

scvg143 表示第143次輸出戚扳。其他字段黄刚,見下圖。

scvg.png

圖片來源于https://colobu.com/2016/07/04/dive-into-go-11/#pprof

scavenger 的工作就是周期性地打掃h(yuǎn)eap中無用的操作系統(tǒng)內(nèi)存分頁胯舷, 它會向操作系統(tǒng)發(fā)出建義王带,請操作系統(tǒng)回收無用內(nèi)存頁埂软,

當(dāng)然并不能強(qiáng)迫操作系統(tǒng)立刻就去做回收處理享言,操作系統(tǒng)可以忽略此建義峻凫,或是延遲回收,比如直到可分配的空閑內(nèi)存不夠的時候览露。

scavenger輸出的信息是我們了解go程序虛擬內(nèi)存空間使用情況的最好方式荧琼, 當(dāng)然你也可以通過其它工具,如free, top來獲到這些信息差牛,
不過你應(yīng)用信任scavenger.

8 參考文獻(xiàn)

講的很好命锄,概述性:https://xenojoshua.com/2019/03/golang-memory/#31-%E7%89%88%E6%9C%AC%E5%8E%86%E5%8F%B2--%E6%BC%94%E8%BF%9B

非常詳細(xì)的文章https://yq.aliyun.com/blog/573819
gc 線上監(jiān)控: http://kuring.me/post/golang-gc/

scavenger: https://studygolang.com/articles/6346

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市偏化,隨后出現(xiàn)的幾起案子脐恩,更是在濱河造成了極大的恐慌,老刑警劉巖侦讨,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件驶冒,死亡現(xiàn)場離奇詭異,居然都是意外死亡韵卤,警方通過查閱死者的電腦和手機(jī)骗污,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來沈条,“玉大人身堡,你說我怎么就攤上這事∨睦穑” “怎么了?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵汞扎,是天一觀的道長季稳。 經(jīng)常有香客問我,道長澈魄,這世上最難降的妖魔是什么景鼠? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮痹扇,結(jié)果婚禮上铛漓,老公的妹妹穿的比我還像新娘。我一直安慰自己鲫构,他們只是感情好浓恶,可當(dāng)我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著结笨,像睡著了一般包晰。 火紅的嫁衣襯著肌膚如雪湿镀。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天伐憾,我揣著相機(jī)與錄音勉痴,去河邊找鬼。 笑死树肃,一個胖子當(dāng)著我的面吹牛蒸矛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播胸嘴,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼雏掠,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了筛谚?” 一聲冷哼從身側(cè)響起磁玉,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎驾讲,沒想到半個月后蚊伞,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡吮铭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年时迫,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片谓晌。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡掠拳,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出纸肉,到底是詐尸還是另有隱情溺欧,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布柏肪,位于F島的核電站姐刁,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏烦味。R本人自食惡果不足惜聂使,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望谬俄。 院中可真熱鬧柏靶,春花似錦、人聲如沸溃论。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽钥勋。三九已至梆靖,卻和暖如春控汉,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背返吻。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工姑子, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人测僵。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓街佑,卻偏偏與公主長得像,于是被迫代替她去往敵國和親捍靠。 傳聞我的和親對象是個殘疾皇子沐旨,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容