1. 程式人生 > >golang垃圾回收和SetFinalizer

golang垃圾回收和SetFinalizer

print 沒有 int fun ack final nali 返回值 設置

golang自帶內存回收機制--GC。GC通過獨立的進程執行,它會搜索不再使用的變量,並釋放。需要註意的是,進行GC會占用機器資源。

GC是自動進行的。如果要手動進行GC,可以調用runtime.GC()函數,進行顯式GC。

SetFinalizer

一個對象object被GC時,如果需要執行一些特殊操作,比如,發信號,或者寫日誌等,可以通過調用函數
func SetFinalizer(obj interface{}, finalizer interface{})來實現。

參數obj必須是指針類型。
參數finalizer是一個函數,其參數類型是obj的類型,並且沒有返回值。

SetFinalizer

設置 obj 關聯函數為 finalizer 。當調用finalizer函數時,其參數是obj

當GC發現obj不可達時,會在另一個獨立的goroutine中執行finalizer(obj)。接著,GC會清除obj的關聯函數。

這樣,obj再次可達,但是已經關聯函數。
如果接下來SetFinalizer沒有被調用, 當下次GC發現obj不可達時,會釋放obj

SetFinalizer只有在對象object被GC時,才會被執行。其他情況下,都不會被執行,即使程序正常結束或者發生錯誤。

Demo

以下代碼中,在函數entry()中定義局部變量,並設置Finalizer,當函數entry()執行完成後,局部變量已經不再使用,會被GC。

在main中,手動觸發GC,查看Finalizer是否被執行。

code

package main

import (
        "log"
        "runtime"
        "time"
)

type Road int

func findRoad(r *Road) {

        log.Println("road:", *r)
}

func entry(){
        var rd Road = Road(999)
        r := &rd

        runtime.SetFinalizer(r, findRoad)
}

func main(){

        entry()

        for i:=0; i < 10; i++ {
                time.Sleep(time.Second)
                runtime.GC()
        }

}

output

2019/02/07 17:27:07 road: 999

參考

SetFinalizer

Go入門指南--垃圾回收

golang垃圾回收和SetFinalizer