<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Go:內(nèi)存管理與內(nèi)存清理

          共 2543字,需瀏覽 6分鐘

           ·

          2021-06-13 00:40

          點(diǎn)擊上方藍(lán)色“Go語言中文網(wǎng)”關(guān)注,每天一起學(xué) Go

          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] ” 中有解釋。

          清理內(nèi)存是一個(gè)過程,它能夠讓 Go 知道哪些內(nèi)存段最近可用于分配。但是,它并不會(huì)使用將位置 0 的方式來清理內(nèi)存。

          將內(nèi)存置 0

          將內(nèi)存置 0 的過程 —— 就是把內(nèi)存段中的所有位賦值為 0 —— 是在分配過程中即時(shí)執(zhí)行的。

          Zeroing the memory

          但是,我們可能想知道 Go 采用什么樣的策略去知道哪些對象能夠用于分配。由于在每個(gè)范圍內(nèi)有一個(gè)內(nèi)部位圖 allocBits,Go 實(shí)際上會(huì)追蹤那些空閑的對象。讓我們從初始態(tài)開始來回顧一下它的工作流程,

          Free objects tracking with allocBits

          就性能角度來看,allocBits 代表了一個(gè)初始態(tài)并且會(huì)保持不變,但是它會(huì)由 freeIndex(一個(gè)指向第一個(gè)空閑位置的增量計(jì)數(shù)器)所協(xié)助。

          然后,第一個(gè)分配就開始了:

          Free objects tracking with allocBits

          freeIndex 現(xiàn)在增加了,并且基于 allocBits 知道了下一段空閑位置。

          分配過程將會(huì)再一次出現(xiàn),之后, GC 將會(huì)啟動(dòng)去釋放不再被使用的內(nèi)存。在標(biāo)記期間,GC 會(huì)用一個(gè)位圖 gcmarkBits 來跟蹤在使用中的內(nèi)存。讓我們通過我們運(yùn)行的程序以相同的示例為例,在第一個(gè)塊不再被使用的地方。

          Memory tracking during the garbage collector

          正在被使用的內(nèi)存被標(biāo)記為黑色,然而當(dāng)前執(zhí)行并不能夠到達(dá)的那些內(nèi)存會(huì)保持為白色。

          有關(guān)更多關(guān)于標(biāo)記和著色階段的信息,我建議你閱讀我的這篇文章 Go:GC 是如何標(biāo)記內(nèi)存的?[2]

          現(xiàn)在,我們可以使用 gomarkBits 精確查看可用于分配的內(nèi)存。Go 現(xiàn)在也使用 gomarkBits 代替了 allocBits ,這個(gè)操作就是內(nèi)存清理:

          Sweeping a span

          但是,這必須在每一個(gè)范圍內(nèi)執(zhí)行完畢并且會(huì)花費(fèi)許多時(shí)間。Go 的目標(biāo)是在清理內(nèi)存時(shí)不阻礙執(zhí)行,并為此提供了兩種策略。

          清理階段

          Go 提供了兩種方式來清理內(nèi)存:

          • 使用一個(gè)工作程序在后臺等待,一個(gè)一個(gè)的清理這些范圍。
          • 當(dāng)分配需要一個(gè)范圍的時(shí)候即時(shí)執(zhí)行。

          關(guān)于后臺工作程序,當(dāng)開始運(yùn)行程序時(shí),Go 將設(shè)置一個(gè)后臺運(yùn)行的 Worker(唯一的任務(wù)就是去清理內(nèi)存),它將進(jìn)入睡眠狀態(tài)并等待內(nèi)存段掃描:

          Background sweeper

          通過追蹤過程的周期,我們也能看到這個(gè)后臺工作程序總是出現(xiàn)去清理內(nèi)存:

          Background sweeper

          清理內(nèi)存段的第二種方式是即時(shí)執(zhí)行。但是,由于這些內(nèi)存段已經(jīng)被分發(fā)到每一個(gè)處理器的本地緩存 mcache 中,因此很難追蹤首先清理哪些內(nèi)存。這就是為什么 Go 首先將所有內(nèi)存段移動(dòng)到 mcentral 的原因。

          Spans are released to the central list

          然后,它將會(huì)讓本地緩存 mcache 再次請求它們,去即時(shí)清理:

          Sweep span on the fly during allocation

          即時(shí)掃描確保所有內(nèi)存段在保存資源的過程中都會(huì)得到清理,同時(shí)會(huì)保存資源以及不會(huì)阻塞程序執(zhí)行。

          與 GC 周期的沖突

          正如之前看到的,由于后臺只有一個(gè) worker 在清理內(nèi)存塊,清理過程可能會(huì)花費(fèi)一些時(shí)間。但是,我們可能想知道如果另一個(gè) GC 周期在一次清理過程中啟動(dòng)會(huì)發(fā)生什么。在這種情況下,這個(gè)運(yùn)行 GC 的 Goroutine 就會(huì)在開始標(biāo)記階段前去協(xié)助完成剩余的清理工作。讓我們舉個(gè)例子看一下連續(xù)調(diào)用兩次 GC,包含數(shù)千個(gè)對象的內(nèi)存分配的過程。

          Sweeping must be finished before a new cycle

          但是,如果開發(fā)者沒有強(qiáng)制調(diào)用 GC,這個(gè)情況并不會(huì)發(fā)生。在后臺運(yùn)行的清理工作以及在執(zhí)行過程中的清理工作應(yīng)該足夠多,因?yàn)榍謇韮?nèi)存塊的數(shù)量和去觸發(fā)一個(gè)新的周期(譯者注:GC 周期)的所需的分配的數(shù)量成正比。

          via:https://medium.com/a-journey-with-go/go-memory-management-and-memory-sweep-cc71b484de05

          作者:Vincent Blanchon[3]譯者:sh1luo[4]校對:polaris1119[5]

          本文由 GCTT[6] 原創(chuàng)編譯,Go 中文網(wǎng)[7] 榮譽(yù)推出

          參考資料

          [1]

          Go:內(nèi)存管理與分配: https://studygolang.com/articles/28436

          [2]

          Go:GC 是如何標(biāo)記內(nèi)存的?: https://studygolang.com/articles/25916

          [3]

          Vincent Blanchon: https://medium.com/@blanchon.vincent

          [4]

          sh1luo: https://github.com/sh1luo

          [5]

          polaris1119: https://github.com/polaris1119

          [6]

          GCTT: https://github.com/studygolang/GCTT

          [7]

          Go 中文網(wǎng): https://studygolang.com/



          推薦閱讀


          福利

          我為大家整理了一份從入門到進(jìn)階的Go學(xué)習(xí)資料禮包,包含學(xué)習(xí)建議:入門看什么,進(jìn)階看什么。關(guān)注公眾號 「polarisxu」,回復(fù) ebook 獲??;還可以回復(fù)「進(jìn)群」,和數(shù)萬 Gopher 交流學(xué)習(xí)。

          瀏覽 54
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  有没有免费av | 国产无码福利在线 | 极品久久久久 | 日本成人在线不卡视频 | 最新在线无码热a |