垃圾回收和cgo

huangapple go评论78阅读模式
英文:

Garbage collection and cgo

问题

在Go语言中,可以通过C代码分配和释放内存,但是垃圾回收器无法直接处理和释放通过C代码分配的内存。如果你想在Go语言中使用一个C库,并且这个库分配了一些需要手动释放的内存,你可以编写一个函数来释放这些内存。

在你的示例代码中,你定义了一个类型Stuff,它是C.Stuff的别名。你可以在NewStuff函数中分配内存,并在Stuff类型上定义一个Free方法来释放内存。但是,垃圾回收器无法自动调用Stuff.Free方法来释放内存。

所以,回答你的问题,垃圾回收器无法在Go运行时中没有对*Stuff的引用时调用Stuff.Free方法。你需要手动调用Stuff.Free方法来释放内存。

希望这样回答对你有帮助。

英文:

Is it possible to make the garbage collector in Go handle and release memory allocated through C code? I apologize, I haven't used C and cgo before so my examples may need some clarification.

Lets say you've got some C library that you'd like to use and this library allocates some memory that needs to be freed manually. What I'd like to do is something like this:

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
}

Is there any way for the garbage collector to call Stuff.Free() when there are no references to *Stuff in the Go runtime?

Am I making sense here?

Perhaps a more direct question is: Is it possible to make the runtime automatically handle the cleanup of C allocated memory by writing a function that the runtime calls when there are zero references to that object?

答案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)
}
英文:

There exists the runtime.SetFinalizer function, but it cannot be used on any object allocated by C code.

However, you can create a Go object for each C object that needs to be freed automatically:

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)
}

huangapple
  • 本文由 发表于 2012年3月3日 01:47:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/9537948.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定