垃圾收集和cgo

时间:2012-03-02 17:47:54

标签: garbage-collection go cgo

是否可以在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分配内存的清理?

1 个答案:

答案 0 :(得分: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)
}