golang之runtime.SetFinaliz

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

在實際的編程中,我們都希望每個對象釋放時執行一個方法,在該方法內執行一些計數、釋放或特定的要求,以往都是在對象指標置nil前調用一個特定的方法,golang提供了runtime.SetFinalizer函數,當GC準備釋放對象時,會回調該函數指定的方法,非常方便和有效。

不過值得注意的是,指標構成的 "迴圈引⽤" 加上 runtime.SetFinalizer 會導致記憶體泄露。

type Data struct {    d   [1024 * 100]byte    o   *Data}func test() {    var a, b Data    a.o = &b    b.o = &a    runtime.SetFinalizer(&a, func(d *Data) { fmt.Printf("a %p final.\n", d) })    runtime.SetFinalizer(&b, func(d *Data) { fmt.Printf("b %p final.\n", d) })}func main() {    for {        test()        time.Sleep(time.Millisecond)    }}

輸出:

$ go build -gcflags "-N -l" && GODEBUG="gctrace=1" ./testgc11(1): 2+0+0 ms, 104 -> 104 MB 1127 -> 1127 (1180-53) objectsgc12(1): 4+0+0 ms, 208 -> 208 MB 2151 -> 2151 (2226-75) objectsgc13(1): 8+0+1 ms, 416 -> 416 MB 4198 -> 4198 (4307-109) objects

記憶體回收行程能正確處理 "指標迴圈引⽤",但⽆法確定 Finalizer 依賴次序,也就⽆法調⽤ Finalizer 函數,這會導致目標對象⽆法變成不可達狀態,其所佔⽤記憶體⽆法被回收。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.