一尘不染

收集Go结构时,是否可以释放非托管资源?

go

我有一个指向由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


阅读 195

收藏
2020-07-02

共1个答案

一尘不染

您可以使用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来完成。

2020-07-02