什么是SetFinalizer(终止器)?
是与对象关联的一个函数。通过runtime.SetFinalizer
设置
特点:
如果对象定义了Finalizer
那么当他被GC
的时候Finalizer
就会被调用,触发例如发信号或者写日志等事件。
GC执行机制的特点:
-
自动进行
-
手动调用:
runtime.GC()
函数进行调用。显式GC
只在某些特殊情况下有用
定义SetFinalizer函数
func SetFinalezer(x, f interfacer{})
参数说明:
-
参数
x
必须是一个指向通过new
申请的对象的指针,或者通过对复合字面值取址得到的指针(x
要么是指针要么指向指针) -
参数
f
必须是一个函数,它接受单个可以直接用x
类型值赋值的参数,也可以有任意个被忽略的返回值(闭包)
SetFinalizer
特点:
-
函数可以将
x
的终止器设置为f
--->当垃圾收集器发现x
不能再直接或间接访问时,它会清理x
并调用f(x)
-
x
的终止器会在x
不能直接或间接访问后的任意时间被调用执行,终止器一般只用于在长期运行的程序中释放关联到某对象的非内存资源--->例如:当一个程序丢弃一个 os.File 对象时没有调用其 Close 方法,该 os.File 对象可以使用终止器去关闭对应的操作系统文件描述符 -
终止器会按依赖顺序执行:如果 A 指向 B,两者都有终止器,且 A 和 B 没有其它关联,那么只有 A 的终止器执行完成,并且 A 被释放后,B 的终止器才可以执行
-
*x
的大小为0字节不会保证终止器执行 -
可以使用
SetFinalizer(x,nil)
来清理绑定到x
上的终止器
终止器只有在对象被 GC 时,才会被执行。其他情况下,都不会被执行,即使程序正常结束或者发生错误
示例代码:
package main
import (
"log"
"runtime"
"time"
)
/*
定义终止器去自动的执行垃圾回收
*/
// 定义一个类型(相当于类)
type Road int
// 定义一个方法,需要传入类型的指针
func findRoad(r *Road) {
// 调用log包下的方法打印指针
log.Println("Road:", *r)
}
// 定义一个函数,定义为终止器
func entry() {
// 定义一个Road对象
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()
}
}