Go的gc沒有jvm成熟;

成都創(chuàng)新互聯(lián)公司專注于柞水企業(yè)網(wǎng)站建設(shè),響應(yīng)式網(wǎng)站開發(fā),成都商城網(wǎng)站開發(fā)。柞水網(wǎng)站建設(shè)公司,為柞水等地區(qū)提供建站服務(wù)。全流程按需網(wǎng)站開發(fā),專業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,成都創(chuàng)新互聯(lián)公司專業(yè)和態(tài)度為您提供的服務(wù)
Go本身也不會(huì)比java產(chǎn)生更多的垃圾(等java有值類型,object在內(nèi)存能連續(xù)分布再說(shuō))。
Go 1.5的gc初步做到精確的、并發(fā)的,STW gc;
相比jvm的G1缺少:可壓縮、可移動(dòng)、分代式的特性。這些以后都會(huì)有。
具體細(xì)節(jié)google一下,有相關(guān)文檔。
CMS過程在上篇文章 GC垃圾回收(2) 中已經(jīng)寫過。
它分為四個(gè)階段:
其中 并發(fā)標(biāo)記 階段會(huì)有漏標(biāo)的問題,為解決這個(gè)問題,采用了 "三色標(biāo)記算法"
G1 GC(Garbage First Garbage Collector)是一種服務(wù)端應(yīng)用使用的垃圾收集器,目標(biāo)是用在 多核、大內(nèi)存 的機(jī)器上,它在大多數(shù)情況下可以實(shí)現(xiàn)指定的GC暫停時(shí)間,同時(shí)還能保持較高的吞吐量。它的吞吐量相較PS+PO降低了大概10%~15%,但是大大降低了響應(yīng)時(shí)間,大概200ms的程度
G1內(nèi)存模型如下:
G1相較之前其它的垃圾回收器,對(duì)模型進(jìn)行了改變,不再進(jìn)行物理分代,采用邏輯分代。
它不再將連續(xù)內(nèi)存分為Eden區(qū)和Old區(qū),而是將內(nèi)存分為一個(gè)個(gè)的Region。一塊Region(分區(qū))在邏輯上依然分代,分為四種:Eden,Old,Survivor,Humongous(大對(duì)象,跨多個(gè)連續(xù)的Region)。
它的每個(gè)分區(qū)都可能是年輕代也可能是老年代,但是在同一時(shí)刻只能屬于某個(gè)代。
年輕代、幸存區(qū)、老年代這些概念還存在,成為了邏輯上的概念,這樣方便復(fù)用之前分代框架的邏輯。在物理上不需要連續(xù),這帶來(lái)了額外的好處——有的分區(qū)內(nèi)垃圾對(duì)象特別多,有的分區(qū)內(nèi)垃圾對(duì)象很少,G1會(huì)優(yōu)先回收垃圾對(duì)象特別多的分區(qū),這樣可以花費(fèi)較少的時(shí)間來(lái)回收這些分區(qū)的垃圾,這也就是G1名字的由來(lái),即首先回收垃圾最多的分區(qū)。
新生代其實(shí)并不適用于這種算法,依然是在新生代滿了的時(shí)候,對(duì)整個(gè)新生代進(jìn)行回收——整個(gè)新生代中的對(duì)象,要么被回收、要么晉升,至于新生代也采取分區(qū)機(jī)制的原因,則是因?yàn)檫@樣跟老年代的策略統(tǒng)一,方便調(diào)整代的大小。
G1還是一種帶壓縮的收集器,在回收老年代的分區(qū)時(shí),是將存活的對(duì)象從一個(gè)分區(qū)拷貝到另一個(gè)可用分區(qū),這個(gè)拷貝的過程就實(shí)現(xiàn)了局部的壓縮。每個(gè)分區(qū)的大小從1M到32M不等,但都是2的冪次方。
特點(diǎn):
G1與CMS在并發(fā)收集時(shí)的算法沒太大區(qū)別,用的是 三色標(biāo)記 算法。但ZGC和Shenandoah使用的是 顏色指針 Colored Pointers。
主要用于分代模型中幫助垃圾回收。
為什么需要 card table ?
尋找存活對(duì)象并不是一件容易的事。從一個(gè)GC root對(duì)象尋找,可能被Old區(qū)對(duì)象引用,這個(gè)Old區(qū)對(duì)象又被Eden區(qū)對(duì)象引用,那么判斷Eden區(qū)對(duì)象是否存活就需要遍歷整個(gè)Old區(qū)存活對(duì)象看是否被Old區(qū)對(duì)象引用。這樣的話每進(jìn)行一次YGC就要掃描整個(gè)Old區(qū)。
所以JVM內(nèi)部,將內(nèi)存區(qū)域分為一個(gè)個(gè)的card,對(duì)象存在一個(gè)個(gè)的card里。當(dāng)老年代某個(gè)card中的對(duì)象指向了年輕代,就會(huì)將這個(gè)card標(biāo)記為 Dirty 。這么多card具體哪個(gè)是 Dirty的,用位圖BitMap來(lái)代表(如0110010010,1表示Dirty),這就是Card Table。
Card Table :由于做YGC時(shí),需要掃描整個(gè)Old區(qū),效率非常低,所以JVM設(shè)計(jì)了Card Table, 如果一個(gè)Old區(qū)Card Table中有對(duì)象指向Y區(qū),就將它設(shè)為Dirty,下次掃描時(shí),只需要掃描Dirty Card。 在結(jié)構(gòu)上,Card Table用BitMap來(lái)實(shí)現(xiàn)。
RSet會(huì)占用一定的空間,所以ZGC又做了改進(jìn),不使用RSet,用顏色指針來(lái)標(biāo)記。
Rset與賦值的效率:
5% ~ 60%(新生代)
G1能跟蹤STW停頓時(shí)間,根據(jù)停頓時(shí)間動(dòng)態(tài)調(diào)整新生代(Y區(qū))比例
超過單個(gè)region的 50% 就是一個(gè)大對(duì)象,也可跨越多個(gè)region。
注意: G1也是存在FGC的,并且一定會(huì)被觸發(fā)。當(dāng)對(duì)象分配不下是會(huì)產(chǎn)生FGC。
回收時(shí)不分新生代還是老年代什么的,region滿了就回收。
MixedGC過程:
跟CMS非常像,MixedGC最后是篩選回收,多了個(gè)篩選步驟。篩選就是找出垃圾最多的region。篩選后將存活對(duì)象復(fù)制到其他region,再將之前的region清空。
CMS和G1在并發(fā)標(biāo)記時(shí)使用的是同一個(gè)算法: 三色標(biāo)記法 ,使用白灰黑三種顏色標(biāo)記對(duì)象。白色是未標(biāo)記;灰色自身被標(biāo)記,引用的對(duì)象未標(biāo)記;黑色自身與引用對(duì)象都已標(biāo)記。
在remark過程中,黑色指向了白色,如果不對(duì)黑色重新掃描,則會(huì)漏標(biāo)。會(huì)把白色D對(duì)象當(dāng)作沒有新引用指向從而回收掉。
并發(fā)標(biāo)記過程中,Mutator刪除了所有從灰色到白色的引用,會(huì)產(chǎn)生漏標(biāo)。此時(shí)白色對(duì)象應(yīng)該被回收
產(chǎn)生漏標(biāo)問題的條件有兩個(gè):
1.黑色對(duì)象指向了白色對(duì)象
2.灰色對(duì)象指向白色對(duì)象的引用消失
所以要解決漏標(biāo)問題,打破兩個(gè)條件之一即可:
為什么G1采用SATB而不用incremental update?
因?yàn)椴捎胕ncremental update把黑色重新標(biāo)記為灰色后,之前掃描過的還要再掃描一遍,效率太低。
G1有RSet與SATB相配合。Card Table里記錄了RSet,RSet里記錄了其他對(duì)象指向自己的引用,這樣就不需要再掃描其他區(qū)域,只要掃描RSet就可以了。
也就是說(shuō) 灰色--白色 引用消失時(shí),如果沒有 黑色--白色,引用會(huì)被push到堆棧,下次掃描時(shí)拿到這個(gè)引用,由于有RSet的存在,不需要掃描整個(gè)堆去查找指向白色的引用,效率比較高。SATB配合RSet渾然天成。
為什么要有GC? 首先JAVA和ASP.NET都有GC 垃圾回收 (garbage collection, GC) 一個(gè)跟蹤過程,它傳遞性地跟蹤指向當(dāng)前使用的對(duì)象的所有指針,以便找到可以引用的所有對(duì)象,然后重新使用在此跟蹤過程中未找到的任何堆內(nèi)存。公共語(yǔ)言運(yùn)行庫(kù)垃圾回收器還壓縮使用中的內(nèi)存,以縮小堆所需要的工作空間 因?yàn)槟銢]有足夠多內(nèi)存,并且,你挺懶,不去自己清理內(nèi)存,所以就有了 GC 什么是GC GC的全稱是garbage collection,中文名稱垃圾回收,是.net中對(duì)內(nèi)存管理的一種功能。垃圾回收器跟蹤并回收托管內(nèi)存中分配的對(duì)象,定期執(zhí)行垃圾回收以回收分配給沒有有效引用的對(duì)象的內(nèi)存。當(dāng)使用可用內(nèi)存不能滿足內(nèi)存請(qǐng)求時(shí),GC會(huì)自動(dòng)進(jìn)行。 在進(jìn)行垃圾回收時(shí),垃圾回收器回首先搜索內(nèi)存中的托管對(duì)象,然后從托管代碼中搜索被引用的對(duì)象并標(biāo)記為有效,接著釋放沒有被標(biāo)記為有效的對(duì)象并收回內(nèi)存,最后整理內(nèi)存將有效對(duì)象挪動(dòng)到一起。這就是GC的四個(gè)步驟。 由上可見,GC是很影響性能的,所以一般說(shuō)來(lái)這種事情況還是盡量少發(fā)生為好。 為了減少一些性能影響,.net的GC支持對(duì)象老化,或者說(shuō)分代的概念,代是對(duì)象在內(nèi)存中相對(duì)存現(xiàn)時(shí)期的度量單位,對(duì)象的代數(shù)或存現(xiàn)時(shí)期說(shuō)明對(duì)象所屬的代。目前.net的垃圾回收器支持三代。每進(jìn)行一次GC,沒有被回收的對(duì)象就自動(dòng)提升一代。較近創(chuàng)建的對(duì)象屬于較新的代,比在應(yīng)用程序生命周期中較早創(chuàng)建的對(duì)象的代數(shù)低。最近代中的對(duì)象位于零代中。
gc 與gccgo 都是go語(yǔ)言標(biāo)準(zhǔn)規(guī)范的不同實(shí)現(xiàn),兩者包含不同的側(cè)重點(diǎn):
使用成本上gccgo遠(yuǎn)比gc更高,基于如下原因:
總結(jié):除非真要追求高性能,否則不建議去折騰gccgo
如果一定要折騰,建議思路:基于gcc docker 鏡像,編寫Dockerfile,安裝golang,然后使用 go build -compiler=gccgo 。
相關(guān)資源:
分享標(biāo)題:go語(yǔ)言gc為什么不分代,gc為什么要分代
網(wǎng)頁(yè)地址:http://chinadenli.net/article30/hsggso.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供動(dòng)態(tài)網(wǎng)站、定制網(wǎng)站、做網(wǎng)站、商城網(wǎng)站、微信小程序、建站公司
聲明:本網(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)