golang垃圾回收該如何分析

這篇文章跟大家分析一下“golang 垃圾回收該如何分析”。內(nèi)容詳細易懂,對“golang 垃圾回收該如何分析”感興趣的朋友可以跟著小編的思路慢慢深入來閱讀一下,希望閱讀后能夠?qū)Υ蠹矣兴鶐椭?。下面跟著小編一起深入學習“golang 垃圾回收該如何分析”的知識吧。

成都創(chuàng)新互聯(lián)公司是一家集網(wǎng)站建設,虹口企業(yè)網(wǎng)站建設,虹口品牌網(wǎng)站建設,網(wǎng)站定制,虹口網(wǎng)站建設報價,網(wǎng)絡營銷,網(wǎng)絡優(yōu)化,虹口網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強企業(yè)競爭力??沙浞譂M足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時我們時刻保持專業(yè)、時尚、前沿,時刻以成就客戶成長自我,堅持不斷學習、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實用型網(wǎng)站。

概述

現(xiàn)代編程語言一般都有垃圾回收功能。這個能極大的減輕程序員的負擔,并且減少大部分場景的問題。要知道,c 語言里面最常見的就是踩內(nèi)存,內(nèi)存泄漏,野指針等問題。golang 作為一個新新語言,自然垃圾回收功能少不了的。當前 golang 的垃圾回收基于的理論是三色標記法,并且通過合理的使用內(nèi)存屏障技術(shù),把垃圾回收的 stw 幾乎消滅(旁白:這個正確的理解,并不是沒有 stw,只是非常非常短了)。

 

GC & RC

首先,內(nèi)存稍高級的管理有兩個方式,了解兩個名詞:

  1. GC:垃圾回收管理內(nèi)存的方式
  2. RC:引用計數(shù)管理內(nèi)存的方式

由于 c 語言自身設計的問題,無法實現(xiàn) GC,所以 c 程序怎么管理內(nèi)存呢?引用計數(shù)就是最常用的稍高級的管理方式。引用計數(shù)怎么用?常用姿勢如下:

  1. 使用前,為了保護對象不被銷毀,計數(shù) +1
  2. 使用完后,計數(shù) -1,計數(shù)減到 0 之后,就可以安全銷毀了
obj_ref(obj);{    do_something ; }obj_unref(obj);
 

引用計數(shù) RC 的使用看上面非常簡單,但其實是非常有講究的,這里不深入了。此處還是由 golang 的垃圾回收展開。

golang 的垃圾回收我們經(jīng)常聽到三色標記法,三色指的是白色,灰色,黑色,分別表示三種狀態(tài),至于三色標記法的理論此處不表,我們從簡單的理解切入。

 

垃圾回收的由來

首先,我們思考下一個不需要思考的問題:垃圾回收是做什么的?golang 為什么需要垃圾回收?

c 程序跑起來是需要內(nèi)存的,棧內(nèi)存由編譯器來管理,堆內(nèi)存由程序員來管理,這個就是 c 程序出內(nèi)存問題的源頭,程序員是人,是人就可能出錯,各種編程人員的素質(zhì)也是參差不齊,實際場景也是各種復雜的情況交織。

所以,我們回歸本源問題,我們本質(zhì)上只是想要一個內(nèi)存而已,管理它只是迫不得已。內(nèi)存用完了,程序員最好也不管。程序員只管用,不管回收。這個就會垃圾回收的由來。

 

逃逸分析的由來

我們再進一步,c 程序還需要程序員自己決定從棧上分配內(nèi)存,還是堆上分配內(nèi)存?

那么這個事情是程序員必須要做的嗎?并不是,本質(zhì)上程序只是需要一個對象,決定這個事情也是迫不得已。

golang 解決這個事情,就是對應的”逃逸分析“。逃逸分析解決一個問題,在保證 golang 程序正確性的前提下,在編譯階段決定對象的分配位置,棧上?堆上?

 

垃圾回收,怎么實現(xiàn)?

底線:golang 只需要保證一個點,回收的一定是不用的垃圾,那么就不會出功能性問題,回收的慢點一定程度都 ok 的。

 

什么樣的是垃圾?

怎么保證回收的一定是垃圾?首先看張圖:

golang 垃圾回收該如何分析
 

 

先說結(jié)論:

  1. 圖上黃色的就是垃圾,這個從圖里一眼就能看出來。沒人用它呀,可不就是垃圾嘛
 

怎么把垃圾找出來?

現(xiàn)在關鍵的問題是:這個黃色塊怎么找出來的?

換個說法:你把在用的找明白,剩下的就是沒在用的垃圾了。什么是在用的呢?從所有的根出發(fā),只要是引用覆蓋到的,就認為在用。

方法:從根處掃描,把所有的根掃描完,每個根掃描到底。按照之前的三色標記來說,掃描完了的是黑色,正在掃描的是灰色的,沒掃描的是白色的。根掃描完了,那么最后只會剩下兩種顏色的,黑色,白色。白色就是沒用的垃圾,這種清理掉就沒事。

問兩個問題

  1. 那么根是什么?
  2. 回收的內(nèi)存是哪里的內(nèi)存?

答案

  1. 棧是根,是掃描的起點,還有一些全局變量也是根,是起點
  2. 所謂垃圾只對于堆上內(nèi)存來說,棧上內(nèi)存是編譯器管理的,堆上內(nèi)存是業(yè)務分配,垃圾回收器回收

下面說另一個關鍵點:怎么掃描是安全的?

  1. 最簡單的思路,我讓世界都停止下來(stw),誰都別動,等我把垃圾找出來,你再運行你的程序吧。這就安全了吧。

還真別說,golang 1.0 就是這么干的。這種實現(xiàn)非常簡單也易于理解,但是無法適用于生產(chǎn)環(huán)境,你一停整個程序,就要暫停業(yè)務,一停就幾秒,所以前期的 golang 根本就不能用呀。

所以呀,為了能夠在線上生產(chǎn)場景使用,而不僅僅是個玩具,那么必須要做到垃圾回收不影響業(yè)務代碼的運行才行。也就是并發(fā)嘍(旁白:不并發(fā)也行,只要你能想到好辦法,能做到:能回收垃圾,又不影響業(yè)務)?簡單的并發(fā)就有要考慮的問題了,先說不安全的例子(掃描和業(yè)務并發(fā)):

初始場景

golang 垃圾回收該如何分析

業(yè)務和掃描并發(fā)

golang 垃圾回收該如何分析

最后結(jié)果

golang 垃圾回收該如何分析

這白色的就是要被回收的,但我們一看就知道,有一個白色的被引用了,回收就野指針了,被回收掉就垮掉了。

 

內(nèi)存屏障

怎么解決這個問題?接下來就是內(nèi)存屏障出場了。golang 內(nèi)存屏障也有一個演進過程:

  1. 插入寫屏障
  2. 混合寫屏障(插入寫屏障 + 刪除寫屏障)

先說屏障的本質(zhì)

  1. 內(nèi)存屏障只是對應一段特殊的代碼
  2. 內(nèi)存屏障這段代碼在編譯期間生成
  3. 內(nèi)存屏障本質(zhì)上在運行期間攔截內(nèi)存寫操作,相當于一個 hook 調(diào)用

屏障的作用

  1. 通過 hook 內(nèi)存的寫操作時機,阻止一些事情的發(fā)生,或者說做好一些標記工作,從而保證垃圾回收的正確性

關于golang 垃圾回收該如何分析就分享到這里啦,希望上述內(nèi)容能夠讓大家有所提升。如果想要學習更多知識,請大家多多留意小編的更新。謝謝大家關注一下創(chuàng)新互聯(lián)網(wǎng)站!

網(wǎng)站名稱:golang垃圾回收該如何分析
文章鏈接:http://muchs.cn/article0/gddsoo.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供手機網(wǎng)站建設、定制網(wǎng)站、軟件開發(fā)域名注冊、網(wǎng)站策劃、外貿(mào)建站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站托管運營