11

是否可以让 Go 中的垃圾收集器处理并释放通过 C 代码分配的内存?抱歉,我之前没有使用过 C 和 cgo,所以我的示例可能需要澄清一下。

假设您有一些想要使用的 C 库,并且该库分配了一些需要手动释放的内存。我想做的是这样的:

package stuff

/*
#include <stuff.h>
*/
import "C"

type Stuff C.Stuff

func NewStuff() *Stuff {
    stuff := Stuff(C.NewStuff()) // Allocate memory

    // define the release function for the runtime to call
    // when this object has no references to it (to release memory)   
    // In this case it's stuff.Free()     

    return stuff

}

func (s Stuff) Free() {
    C.Free(C.Stuff(s)) // Release memory
}

当 Go 运行时中没有对 *Stuff 的引用时,垃圾收集器有什么方法可以调用 Stuff.Free() 吗?

我在这里有意义吗?

也许更直接的问题是:是否有可能通过编写一个在对该对象的引用为零时运行时调用的函数来使运行时自动处理 C 分配的内存的清理?

4

1 回答 1

14

该函数存在runtime.SetFinalizer,但不能用于任何由 C 代码分配的对象。

但是,您可以为每个需要自动释放的 C 对象创建一个 Go 对象:

type Stuff struct {
    cStuff *C.Stuff
}

func NewStuff() *Stuff {
    s := &Stuff{C.NewStuff()}
    runtime.SetFinalizer(s, (*Stuff).Free)
    return s
}

func (s *Stuff) Free() {
    C.Free(s.cStuff)
}
于 2012-03-02T18:27:45.857 回答