golang将指针传给cgo后还能被回收吗?

问题:

如果把golang分配的变量,其指针通过cgo传给c,并被c存储,那这个变量还能被gc回收吗?

实验代码:

test_memory_leak.go

Go 复制代码
package main

/*
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

char* cMalloc() {
	char *mem = (char*)malloc(1024 * 1024 * 16);
	return mem;
}

void cMemset(char* mem) {
	memset(mem, '-', 1024 * 1024 * 16);
}

int arrLen = 1000;
int arrIndex;
char* globalMemAddr[1000];

void printAddr(char* mem) {
	if (arrIndex+1 >= arrLen) {
		arrIndex = 0;
	} else {
		arrIndex++;
	}
	globalMemAddr[arrIndex] = mem;
	printf("index: %d, addr: %p\n", arrIndex, globalMemAddr[arrIndex]);
}
*/
import "C"
import (
	"fmt"
	"net/http"
	_ "net/http/pprof"
	"os"
	"sync"
	"time"
	"unsafe"
)

var size int = 1024 * 1024 * 16

func main() {
	go func() {
		_ = http.ListenAndServe("0.0.0.0:9091", nil)
	}()
	if len(os.Args) > 1 && os.Args[1] == "1" {
		var wg sync.WaitGroup
		for {
			wg.Add(1)
			go doCMalloc(&wg)
			wg.Wait()
			time.Sleep(500 * time.Millisecond)
		}
	} else {
		var wg sync.WaitGroup
		for {
			wg.Add(1)
			go doGoMalloc(&wg)
			wg.Wait()
			time.Sleep(500 * time.Millisecond)
		}
	}
}

// 无泄漏
func doCMalloc(wg *sync.WaitGroup) {
	defer wg.Done()
	cptr := C.cMalloc()
	C.cMemset(cptr)
	C.printAddr(cptr)
	bs := C.GoBytes(unsafe.Pointer(cptr), C.int(size))
	fmt.Printf("1: %s .. %s\n", string(bs[0:8]), string(bs[size-8:size]))
	C.free(unsafe.Pointer(cptr))
}

// 无泄漏
func doGoMalloc(wg *sync.WaitGroup) {
	defer wg.Done()
	bs := make([]byte, size, size)
	cptr := (*C.char)(unsafe.Pointer(&bs[0]))
	C.cMemset(cptr)
	C.printAddr(cptr)
	fmt.Printf("2: %s .. %s\n", string(bs[0:8]), string(bs[size-8:size]))
}

运行代码分支2:

GODEBUG=gctrace=1 ./test_memory_leak 2

终端显示:

top显示:

pprof数据:

go tool pprof -http=10.10.10.244:9000 http://127.0.0.1:9091/debug/pprof/allocs

alloc_objects:

inuse_space:

观察到的数据:

1、变量地址始终在0xc000180000和0xc001200000之间交换,说明内存被回收重复利用。

2、每次gc结束后内存始终控制在16MB。

3、进程使用的内存始终在40多MB,并没有太大变化。

4、inuse_space保持16MB不变,而alloc_objects在不断增长。

结论:

golang分配的变量,其指针被cgo引用,不影响golang对其进行垃圾回收。

--end--

相关推荐
巷北夜未央7 分钟前
数据结构之二叉树Python版
开发语言·数据结构·python
草海桐27 分钟前
golang 的github.com/dgrijalva/jwt-go包
golang·jwt·jwt-go
旧识君30 分钟前
移动端1px终极解决方案:Sass混合宏工程化实践
开发语言·前端·javascript·前端框架·less·sass·scss
郝YH是人间理想1 小时前
OpenCV基础——傅里叶变换、角点检测
开发语言·图像处理·人工智能·python·opencv·计算机视觉
Tiger Z1 小时前
R 语言科研绘图第 36 期 --- 饼状图-基础
开发语言·程序人生·r语言·贴图
揣晓丹1 小时前
JAVA实战开源项目:校园失物招领系统(Vue+SpringBoot) 附源码
java·开发语言·vue.js·spring boot·开源
霍徵琅1 小时前
Groovy语言的物联网
开发语言·后端·golang
独好紫罗兰2 小时前
洛谷题单3-P1420 最长连号-python-流程图重构
开发语言·python·算法
kingmax542120082 小时前
深入解析:使用Python爬取Bilibili视频
开发语言·python·音视频
申雪菱2 小时前
Scheme语言的数据挖掘
开发语言·后端·golang