新聞中心
Go語言自帶垃圾回收機(jī)制(GC)。GC 通過獨(dú)立的進(jìn)程執(zhí)行,它會搜索不再使用的變量,并將其釋放。需要注意的是,GC 在運(yùn)行時會占用機(jī)器資源。

GC 是自動進(jìn)行的,如果要手動進(jìn)行 GC,可以使用 runtime.GC() 函數(shù),顯式的執(zhí)行 GC。顯式的進(jìn)行 GC 只在某些特殊的情況下才有用,比如當(dāng)內(nèi)存資源不足時調(diào)用 runtime.GC() ,這樣會立即釋放一大片內(nèi)存,但是會造成程序短時間的性能下降。
finalizer(終止器)是與對象關(guān)聯(lián)的一個函數(shù),通過 runtime.SetFinalizer 來設(shè)置,如果某個對象定義了 finalizer,當(dāng)它被 GC 時候,這個 finalizer 就會被調(diào)用,以完成一些特定的任務(wù),例如發(fā)信號或者寫日志等。
在Go語言中 SetFinalizer 函數(shù)是這樣定義的:
func SetFinalizer(x, f interface{})
參數(shù)說明如下:
- 參數(shù) x 必須是一個指向通過 new 申請的對象的指針,或者通過對復(fù)合字面值取址得到的指針。
- 參數(shù) f 必須是一個函數(shù),它接受單個可以直接用 x 類型值賦值的參數(shù),也可以有任意個被忽略的返回值。
SetFinalizer 函數(shù)可以將 x 的終止器設(shè)置為 f,當(dāng)垃圾收集器發(fā)現(xiàn) x 不能再直接或間接訪問時,它會清理 x 并調(diào)用 f(x)。
另外,x 的終止器會在 x 不能直接或間接訪問后的任意時間被調(diào)用執(zhí)行,不保證終止器會在程序退出前執(zhí)行,因此一般終止器只用于在長期運(yùn)行的程序中釋放關(guān)聯(lián)到某對象的非內(nèi)存資源。例如,當(dāng)一個程序丟棄一個 os.File 對象時沒有調(diào)用其 Close 方法,該 os.File 對象可以使用終止器去關(guān)閉對應(yīng)的操作系統(tǒng)文件描述符。
終止器會按依賴順序執(zhí)行:如果 A 指向 B,兩者都有終止器,且 A 和 B 沒有其它關(guān)聯(lián),那么只有 A 的終止器執(zhí)行完成,并且 A 被釋放后,B 的終止器才可以執(zhí)行。
如果 *x 的大小為 0 字節(jié),也不保證終止器會執(zhí)行。
此外,我們也可以使用
SetFinalizer(x, nil)來清理綁定到 x 上的終止器。
提示:終止器只有在對象被 GC 時,才會被執(zhí)行。其他情況下,都不會被執(zhí)行,即使程序正常結(jié)束或者發(fā)生錯誤。
【示例】在函數(shù) entry() 中定義局部變量并設(shè)置 finalizer,當(dāng)函數(shù) entry() 執(zhí)行完成后,在 main 函數(shù)中手動觸發(fā) GC,查看 finalizer 的執(zhí)行情況。
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()
}
}
運(yùn)行結(jié)果如下:
2019/11/28 15:32:16 road: 999
分享標(biāo)題:創(chuàng)新互聯(lián)GO教程:Go語言垃圾回收和SetFinalizer
鏈接URL:http://fisionsoft.com.cn/article/dhgsheo.html


咨詢
建站咨詢
