大家好,我是小棧君催烘,因為個人和工作的緣故,所以拖更了一點時間缎罢,但是關(guān)于拖更的內(nèi)容小棧君會在后續(xù)的時間中補回來伊群,還希望大家繼續(xù)支持和關(guān)注小棧君喳钟。當(dāng)然,在國內(nèi)疫情稍微減緩的情況下在岂,小棧君在這里也多說兩句奔则,在非常時刻,我們應(yīng)當(dāng)保持警惕蔽午,清洗手易茬,多通風(fēng),避免人群聚集及老,希望大家平安健康抽莱,
閑話不多說,我們直接進(jìn)入正題骄恶,今天給大家分享的事關(guān)于Go語言中的GC食铐,本期的分享并沒有多少代碼可言,都是一些理論知識僧鲁,希望大家耐心且看完虐呻,因為能力有限,所以這邊小棧君會盡量用大白話來進(jìn)行敘述寞秃,如有錯誤之處斟叼,還請多多諒解。
GC含義:
對于編程有經(jīng)驗的同學(xué)應(yīng)該都知道GC春寿,他的英文全稱是garbage collector 朗涩,也就是我們通常所說的垃圾收集器。其實Go語言的垃圾收集器是相對于C++語言有十分重要的改進(jìn)绑改,針對于開發(fā)過C++的同學(xué)或是大學(xué)的時候?qū)W習(xí)的C++知識而言的話谢床,我們應(yīng)該知道在C++語言中創(chuàng)建對象分配空間后需要手動釋放,針對于手動釋放的情況下厘线,有時候我們很難去進(jìn)行判斷什么時候需要识腿,在編程的難度方面無疑是大大增加了難度。
GO語言GC的發(fā)展:
Go語言的GC問題皆的,其實經(jīng)歷過多個版本的迭代覆履,并非一蹴而就,就像我們做編程的一樣并非一生下來就會费薄。他也是經(jīng)歷過一定時間的發(fā)展史硝全。在1.1版本的時候Go語言采用的STW也就是stop the word,也就是我們常說的標(biāo)記清掃的方式楞抡,在此期間容器是不會執(zhí)行我們的應(yīng)用程序伟众,所以也會被人所詬病。在Go語言1.3版本之后召廷,Go語言的團(tuán)隊進(jìn)行分離了標(biāo)記和清楚的操作凳厢,使用了協(xié)程進(jìn)行并發(fā)執(zhí)行清理账胧,也就是在標(biāo)記的時候進(jìn)行Mark STW,sweep的時候并發(fā)執(zhí)行先紫。它所代表的的執(zhí)行過程大致如下:在進(jìn)行GC的時候治泥,Go語言會首先停止運行我們的程序,進(jìn)行遞歸遍歷對象遮精,進(jìn)行標(biāo)記居夹,標(biāo)記完成之后將所有沒有引用的對象進(jìn)行清理。由于標(biāo)記會進(jìn)行程序的停止本冲,所以當(dāng)對象特別多的時候標(biāo)記和清理的時間就會相對的延長(有可能是幾百毫秒)准脂,對于大型的項目而言無疑是很難受的。
所以在Go語言的1.5版本中針對于標(biāo)記和清理算法的改進(jìn)檬洞,引入了三色標(biāo)記法狸膏。從邏輯上進(jìn)行劃分為幾大區(qū)域,白色區(qū)域[未搜索]添怔、灰色區(qū)域[正搜索]湾戳、黑色區(qū)域[已搜索]。
其運行的原理大致如下:
程序運行之初澎灸,針對于創(chuàng)建的對象都作為白色的標(biāo)記院塞。然后當(dāng)我們的GC開始的時候,我們將所有可達(dá)的對象都標(biāo)記為灰色
然后標(biāo)記為黑色之后性昭,在以灰色為基點進(jìn)行可達(dá)分析,找到其引用的對象县遣,然后將其引用的對象標(biāo)記為灰色糜颠,自己則變成黑色。
依次進(jìn)行循環(huán)萧求,最終將所有可達(dá)的對象標(biāo)記為黑色其兴,以便于系統(tǒng)區(qū)分。
然后系統(tǒng)再回收白色未標(biāo)記的對象夸政,釋放內(nèi)存元旬。
大體的三色標(biāo)記法的過程就是這樣。當(dāng)然Go語言的團(tuán)隊每次的更新都會對GC算法進(jìn)行優(yōu)化守问,比如在golang1.5版本的時候支持了并發(fā)的收集匀归,在1.8的時候已經(jīng)將STW的時間優(yōu)化到了100微妙。通常來講在我們應(yīng)用程序上一次時間只需要10微妙耗帕,而且在1.10版本之后再次減少了GC對于CPU的使用率穆端。
當(dāng)然值得注意一點的是,和java程序一樣程序?qū)τ贕C的這個動作是自發(fā)進(jìn)行的仿便。在下列的情況下會進(jìn)行觸發(fā)GC体啰。一種情況是程序申請內(nèi)存空間時攒巍,發(fā)現(xiàn)GC是上次GC的兩倍,另一種情況是程序在運行過程中荒勇,每2分鐘會進(jìn)行GC的觸發(fā)柒莉。
GC的調(diào)優(yōu)
這里小棧君粗略的講解一下關(guān)于GC的調(diào)優(yōu)吧,第一是我們在程序編寫的過程中沽翔,要做到盡量的小對象復(fù)用常柄,針對于局部變量盡量少去聲明,針對于多個小對象的情況我們可以用一個結(jié)構(gòu)體進(jìn)行包裝搀擂,方便GC的掃描西潘。其次就是少用string的“+進(jìn)行字符串的拼接。
最后在go源碼中也有對于GC的相關(guān)描述:
在runtime包中哨颂,這里團(tuán)隊寫了關(guān)于GC的詳細(xì)流程喷市,包括GC率和標(biāo)記方式等等,感興趣的朋友可以下來看一下威恼,如果英文不是很好的話品姓,可以自行搜索翻譯,哈哈哈哈箫措。
好了腹备,今天的淺嘗分析go語言的GC就先到這里了,如果你喜歡我的分享斤蔓,還請記得多多轉(zhuǎn)發(fā)植酥,點贊,我是小棧君弦牡,我們下期分享再見~友驮,拜了個拜
本文由博客一文多發(fā)平臺 OpenWrite 發(fā)布!