<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 runtime.KeepAlive?

          共 901字,需瀏覽 2分鐘

           ·

          2021-11-29 21:05

          些同學(xué)喜歡利用 runtime.SetFinalizer 模擬析構(gòu)函數(shù),當(dāng)變量被回收時(shí),執(zhí)行一些回收操作,加速一些資源的釋放。在做性能優(yōu)化的時(shí)候這樣做確實(shí)有一定的效果,不過(guò)這樣做是有一定的風(fēng)險(xiǎn)的。

          比如下面這段代碼,初始化一個(gè)文件描述符,當(dāng) GC 發(fā)生時(shí)釋放掉無(wú)效的文件描述符。


          type?File?struct?{?d?int?}

          func?main()?{
          ????p?:=?openFile("t.txt")
          ????content?:=?readFile(p.d)

          ????println("Here?is?the?content:?"+content)
          }

          func?openFile(path?string)?*File?{
          ????d,?err?:=?syscall.Open(path,?syscall.O_RDONLY,?0)
          ????if?err?!=?nil?{
          ??????panic(err)
          ????}

          ????p?:=?&Filego7utgvlrp
          ????runtime.SetFinalizer(p,?func(p?*File)?{
          ??????syscall.Close(p.d)
          ????})

          ????return?p
          }

          func?readFile(descriptor?int)?string?{
          ????doSomeAllocation()

          ????var?buf?[1000]byte
          ????_,?err?:=?syscall.Read(descriptor,?buf[:])
          ????if?err?!=?nil?{
          ??????panic(err)
          ????}

          ????return?string(buf[:])
          }

          func?doSomeAllocation()?{
          ????var?a?*int

          ????//?memory?increase?to?force?the?GC
          ????for?i:=?0;?i?10000000;?i++?{
          ??????i?:=?1
          ??????a?=?&i
          ????}

          ????_?=?a
          }

          上面這段代碼是對(duì) go 官方文檔[1]的一個(gè)延伸,doSomeAllocation 會(huì)強(qiáng)制執(zhí)行 GC,當(dāng)我們執(zhí)行這段代碼時(shí)會(huì)出現(xiàn)下面的錯(cuò)誤。

          panic:?no?such?file?or?directory

          goroutine?1?[running]:
          main.openFile(0x107a65e,?0x5,?0x10d9220)
          ????????main.go:20?+0xe5
          main.main()
          ????????main.go:11?+0x3a

          這是因?yàn)?syscall.Open 產(chǎn)生的文件描述符比較特殊,是個(gè) int 類型,當(dāng)以值拷貝的方式在函數(shù)間傳遞時(shí),并不會(huì)讓 File.d 產(chǎn)生引用關(guān)系,于是 GC 發(fā)生時(shí)就會(huì)調(diào)用 runtime.SetFinalizer(p, func(p *File) 導(dǎo)致文件描述符被 close 掉。

          什么是 runtime.KeepAlive ?

          如上面的例子,我們?nèi)绻拍茏屛募枋龇槐?gc 給釋放掉呢?其實(shí)很簡(jiǎn)單,只需要調(diào)用 runtime.KeepAlive 即可。

          func?main()?{
          ????p?:=?openFile("t.txt")
          ????content?:=?readFile(p.d)
          ????
          ????runtime.KeepAlive(p)

          ????println("Here?is?the?content:?"+content)
          }

          runtime.KeepAlive 能阻止 runtime.SetFinalizer 延遲發(fā)生,保證我們的變量不被 GC 所回收。

          結(jié)論

          正常情況下,runtime.KeepAlive,runtime.SetFinalizer 不應(yīng)該被濫用,當(dāng)我們真的需要使用時(shí)候,要注意使用是否合理。

          《性能優(yōu)化 | Go Ballast 讓內(nèi)存控制更加絲滑》我們說(shuō)到如何讓整個(gè)程序的聲明周期內(nèi)維護(hù)一個(gè) slice 不被 gc 給回收掉,這里就用到了 runtime.KeepAlive。

          這里還有有一篇關(guān)于 runtime.KeepAlive 的文檔[2],有興趣的可以看一下。

          寫文章不易請(qǐng)大家?guī)兔c(diǎn)擊 在看,點(diǎn)贊,分享。

          參考資料

          [1]

          go 官方文檔: https://pkg.go.dev/runtime#KeepAlive

          [2]

          文檔: https://medium.com/a-journey-with-go/go-keeping-a-variable-alive-c28e3633673a



          瀏覽 35
          點(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>
                  六月丁香深深爱 | 欧美成人性爱无码视频 | 免费性爱视频在线观看 | 婷婷性爱五月天 | 一本人妻无码 |