<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)存清理

          共 2557字,需瀏覽 6分鐘

           ·

          2020-08-19 22:14

          點(diǎn)擊上方藍(lán)色“Go語言中文網(wǎng)”關(guān)注我們,領(lǐng)全套Go資料,每天學(xué)習(xí)?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 采用什么樣的策略去知道哪些對(duì)象能夠用于分配。由于在每個(gè)范圍內(nèi)有一個(gè)內(nèi)部位圖 allocBits ,Go 實(shí)際上會(huì)追蹤那些空閑的對(duì)象。讓我們從初始態(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)存的?]( "Go:GC 是如何標(biāo)記內(nèi)存的?") 現(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è)工作程序在后臺(tái)等待,一個(gè)一個(gè)的清理這些范圍。
          • 當(dāng)分配需要一個(gè)范圍的時(shí)候即時(shí)執(zhí)行。

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

          Background sweeper

          通過追蹤過程的周期,我們也能看到這個(gè)后臺(tái)工作程序總是出現(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` 再次請(qǐng)求它們,去即時(shí)清理:

          Sweep span on the fly during allocation

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

          與 GC 周期的沖突

          正如之前看到的,由于后臺(tái)只有一個(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è)對(duì)象的內(nèi)存分配的過程。

          Sweeping must be finished before a new cycle

          但是,如果開發(fā)者沒有強(qiáng)制調(diào)用 GC,這個(gè)情況并不會(huì)發(fā)生。在后臺(tái)運(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[2]譯者:

          [3]校對(duì):polaris1119[4]

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

          參考資料

          [1]

          Go:內(nèi)存管理與分配: https://medium.com/a-journey-with-go/go-memory-management-and-allocation-a7396d430f44

          [2]

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

          [3]

          sh1luo: https://github.com/sh1luo

          [4]

          polaris1119: https://github.com/polaris1119

          [5]

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

          [6]

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



          推薦閱讀


          學(xué)習(xí)交流 Go 語言,掃碼回復(fù)「進(jìn)群」即可


          站長(zhǎng) polarisxu

          自己的原創(chuàng)文章

          不限于 Go 技術(shù)

          職場(chǎng)和創(chuàng)業(yè)經(jīng)驗(yàn)


          Go語言中文網(wǎng)

          每天為你

          分享 Go 知識(shí)

          Go愛好者值得關(guān)注


          瀏覽 53
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

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

          手機(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色偷偷 | 韩国少妇无码 | 黄色99| 无码在线观看高清视频 |