go cgo gc
原文链接: go cgo gc
cgo调用内存泄露:C.GostringN()生成的string不会被GC?
package main
/*
#include <stdlib.h>
#include <malloc.h>
void mal(char **p) {
int l = 1000000;
*p= (char *)malloc(l);
*(*p+l-2) = 'a';
*(*p+l-1) = 'b';
}
*/
import "C"
import (
"fmt"
"sync"
"time"
"unsafe"
)
func main() {
time.Sleep(time.Second * 10)
var wg sync.WaitGroup
for i := 0; i < 1000; i++ {
wg.Add(1)
go func() {
var p *C.char
C.mal(&p)
defer C.free(unsafe.Pointer(p))
l := 1000000
ss := C.GoStringN(p, C.int(l)) // ss不会被GC
if string(ss[l-2:]) != "ab" {
fmt.Println("not ab")
}
wg.Done()
}()
}
wg.Wait()
fmt.Println("complete!")
time.Sleep(time.Second * 300)
}
注意:
GoStringN是拷贝缓冲区生成新对象。https://golang.org/cmd/cgo/#hdr-Go_references_to_CA few special functions convert between Go and C types by making copies of the data. 不是GoStringN结果没被GC,是C里malloc出来的东西需要自己手工free掉。