<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 語(yǔ)言中 runtime.KeepAlive() 方法的一些隨筆

          共 2607字,需瀏覽 6分鐘

           ·

          2021-04-28 17:23

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

          我在看 go101 網(wǎng)站的 類型不安全指針[1](來源)[2] 一文時(shí),偶然發(fā)現(xiàn)了 runtime[3] 庫(kù)的一個(gè)有趣的新方法 runtime.KeepAlive()[4] 的一個(gè)用法。剛開始我對(duì)于怎么使用它是很困惑的, 那么按我的性格肯定要探究它是怎么工作的。

          runtime.KeepAlive 所做的事就是使一個(gè)變量保持 '存活',這就意味著它(或者它引用的變量)不會(huì)被垃圾收集,而且它所注冊(cè)的任何終止器(finalizer)都不會(huì)被執(zhí)行。這個(gè)文檔[5] 中有一個(gè)如何使用它的例子。我的第一個(gè)疑問是為什么在代碼中 runtime.KeepAlive() 的使用時(shí)機(jī)那么的靠后;我比較希望它能夠更早的被調(diào)用,就像終止器被注入時(shí),但是后來我明白了它這樣做的真正意圖。簡(jiǎn)而言之, runtime.KeepAlive() 是調(diào)用一下變量。顯而易見的,一個(gè)變量直至它的最后一次使用期間都是存活的,所以如果你在后面使用一個(gè)變量,那么 Go 必須讓它一直存活到最后使用的時(shí)候。

          一方面,runtime.keepAlive 沒有什么神奇的地方;任何一種使用某個(gè)變量的方式,都會(huì)使它保持存活。另一方面,runtime.KeepAlive() 是一種很重要的魔法,它表示 Go 保證了你所使用的變量不會(huì)被優(yōu)化清除掉,因?yàn)榫幾g器能明白沒有什么能真正依賴于你的使用。雖然有很多其它的方式來使用一個(gè)變量,但即使是最聰明的方式也很容易受到編譯器的影響,最聰明的方式也會(huì)有不利的一面,他們會(huì)影響 Go 的智能合理逃逸分析[6],強(qiáng)行將一個(gè)本屬于本地棧的變量分配到堆上。

          關(guān)于 runtime.KeepAlive() 的另一個(gè)特殊戲法是它的是實(shí)現(xiàn)方式,代碼里什么都沒做。實(shí)際上,它不是作為一個(gè)被調(diào)用的函數(shù),而是由 ssa.go[7] 實(shí)現(xiàn)的編譯器內(nèi)部實(shí)現(xiàn),類似于 unsafe.Pointer。當(dāng)你的代碼中使用了 runtime.KeepAlive(),Go 編譯器會(huì)設(shè)置一個(gè)名為 OpKeepAlive 的靜態(tài)單賦值(SSA),然后剩余的編譯就會(huì)知道將這個(gè)變量的存活期保證到使用了 runtime.KeepAlive() 的時(shí)刻。

          (閱讀 ssa.go 的初始化函數(shù)是很有趣的。不出所料,有許多語(yǔ)義化包函數(shù)調(diào)用被直接映射到將指令內(nèi)聯(lián)在代碼中,如 math.Sqrt。有些是平臺(tái)相關(guān)的,包括 bits[8] 的函數(shù))

          runtime.KeepAlive() 是一個(gè)特別的魔法有一個(gè)直接的后果就是你不能得到它的地址。如果你這樣做的話, Go 會(huì)報(bào)錯(cuò):

          ./tst.go:20:22: cannot take the address of runtime.KeepAlive

          我不知道 Go 是否會(huì)聰明地優(yōu)化掉一個(gè)只調(diào)用 runtime.KeepAlive 的函數(shù), 但希望你永遠(yuǎn)不需要間接調(diào)用 runtime.KeepAlive

          PS:盡管我很想說沒有人應(yīng)該需要對(duì)分配在棧上的本地變量(包括參數(shù))調(diào)用 runtime.KeepAlive,因?yàn)樵诤瘮?shù)返回之前棧是不會(huì)被回收的,但這是一個(gè)危險(xiǎn)的假設(shè)。編譯器可以非常聰明地為兩個(gè)不同的、沒有重疊生存期的變量重用堆棧槽,或者簡(jiǎn)單地告訴垃圾收集它已經(jīng)完成了某些工作(例如,用 nil 覆蓋指向?qū)ο蟮闹羔槪?/p>


          via: https://utcc.utoronto.ca/~cks/space/blog/programming/GoRuntimeKeepAliveNotes

          作者:ChrisSiebenmann[9]譯者:yuhang-dong[10]校對(duì):unknwon[11]

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

          參考資料

          [1]

          類型不安全指針: https://go101.org/article/unsafe.html

          [2]

          (來源): https://old.reddit.com/r/golang/comments/8ll6lf/how_to_safely_use_typeunsafe_pointers_in_go/

          [3]

          runtime: https://golang.org/pkg/runtime/

          [4]

          runtime.KeepAlive(): https://golang.org/pkg/runtime/#KeepAlive

          [5]

          這個(gè)文檔: https://golang.org/pkg/runtime/#KeepAlive

          [6]

          Go 的智能合理逃逸分析: https://utcc.utoronto.ca/~cks/space/blog/programming/GoReflectEscapeHack

          [7]

          ssa.go: https://github.com/golang/go/blob/master/src/cmd/compile/internal/gc/ssa.go#L2828

          [8]

          bits: https://golang.org/pkg/math/bits/

          [9]

          ChrisSiebenmann: https://utcc.utoronto.ca/~cks/space/People/ChrisSiebenmann

          [10]

          yuhang-dong: https://github.com/yuhang-dong

          [11]

          unknwon: https://github.com/unknwon

          [12]

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

          [13]

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



          推薦閱讀


          福利

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

          瀏覽 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>
                  欧美午夜操逼大片 | 91av-91av在线盒子 | 亚洲黄色免费网站 | 亚洲欧视频在线播放 | 欧美日本美女网18 |