stringSlice转换——无需内存copy,这是之前写过的一篇文章,可以将结构体,byte,string以指针这种形式达到转换的作用,效率非常高效,可以说是黑魔法

而问题也就是出现在这里了。在使用过程中,我出现了sweep increased allocation count错误。

这个问题是什么,其为什么会出现呢?是使用pointer的问题吗?

首先,我需要找到这个问题是什么产生的?

由于我从C语言带过来的习惯,所以,对于指针的运用也和C的操作类似。

1
2
3
4
5
6
7
8
9
type tyEMMCLOGData struct {
bDataValidity byte //数据有效性: 0 数据无效 1有效 2传输完成
tLogs [80]Log //写的log内容
}

func BytesToTyEMMCLOGData(b []byte) *tyEMMCLOGData {
return (*tyEMMCLOGData)(unsafe.Pointer(
(*reflect.SliceHeader)(unsafe.Pointer(&b)).Data))
}

从其他地方接收的byte数据,通过函数BytesToTyEMMCLOGData转换成struct,由于C的习惯,即使其传回来一个byte,一样可以使用这样的方式去转换,只要访问结构体时,不超过实际一个字节的数据即可

于是便出现了这样的问题。

image-20191218120123591

为什么会出现?

问题的出现,可以查到是GC的打印,查过一些资料后,其实没有得到什么答案,不过根据我的看法猜测:

通过上述的操作,我们已经在内存中引用了一段无效的内存,也就是为我们的程序构造了一个访问非法内存地址的入口。

然后在GC回收我们以指针的方式构造的结构体的时(实际这个结构退只有一字节),我们的指针操作对GC来说是未知的,所以GC会去回收整个结构体的大小,但是由于这个结构体实际除了一个字节是合法字节,其他字节都是非法的,操作非法内存,系统发出SIGSEGV 信号,程序崩溃。

附在最后:

看到GC中对pointer的处理:https://purewhite.io/2019/04/01/golang-gc-consider-unsafe/

原文:https://groups.google.com/forum/#!msg/golang-nuts/yNis7bQG_rY/yaJFoSx1hgIJ