有没有办法在收集Go结构时释放非托管资源?

时间:2012-08-04 19:49:35

标签: garbage-collection interop go cgo

我有一个指向由Go结构包装的C类型的指针,如下所示:

type Wrapper struct {
    unmanaged *C.my_c_type
}

C类型又具有以下功能:

my_c_type* make_c_type();
void free_c_type(my_c_type *ct);

有没有办法可以确保在free_c_type实例完成后调用Wrapper

1 个答案:

答案 0 :(得分:21)

您可以使用runtime.SetFinalizer。这允许您在对象超出范围时运行清理功能。它不能保证运行。但是,在释放内存时,这并不重要。重要的是,对于长时间运行的过程,它可能会控制垃圾。

以下是文档的一些摘录(整段删除):

  

SetFinalizer将与x关联的终结器设置为f。当垃圾收集器找到具有关联终结器的无法访问的块时,它会清除关联并在单独的goroutine中运行f(x)。这使x再次可达,但现在没有关联的终结器。假设没有再次调用SetFinalizer,下次垃圾收集器看到x无法访问时,它将释放x。

     

x的终结器计划在x无法访问后的某个任意时间运行。无法保证终结器将在程序退出之前运行,因此通常它们仅用于在长时间运行的程序期间释放与对象关联的非内存资源。例如,当程序在不调用Close的情况下丢弃os.File时,os.File对象可以使用终结器关闭关联的操作系统文件描述符,但是依赖于终结器来刷新内存中的I是错误的。 / O缓冲区,如bufio.Writer,因为缓冲区不会在程序退出时刷新。

     

单个goroutine按顺序运行程序的所有终结器。如果终结器必须运行很长时间,它应该通过启动一个新的goroutine来实现。