仅保留引用不赋值给变量是否安全?Go切片引用稳定性问询
Go中Slice保存临时结构体引用的安全性问题
我希望在slice中保存一组引用,但不确定仅保留引用而不将结构体赋值给变量是否安全——操作系统会不会往这些引用指向的地址写入预期外的数据?示例代码如下:
type ListItem [8]uint64 list := make([]*ListItem, 0) list = append(list, &ListItem{}) list = append(list, &ListItem{}) list = append(list, &ListItem{})
换句话说,能不能保证程序运行期间,slice「list」里的元素始终保持不变,不管运行多久?
这种写法在Go语言里是安全的,slice中保存的引用指向的结构体不会被操作系统或Go运行时意外覆盖,具体原因如下:
- Go的可达性GC机制:只要
list这个slice本身是可达的(比如被全局变量、当前goroutine的栈变量持有),它所引用的所有ListItem结构体都会被判定为存活对象,垃圾回收器不会回收这些内存,也不会有任何操作去覆盖这块内存区域。 - 临时结构体的内存管理:像
&ListItem{}这种直接取临时结构体地址的写法,编译器会根据结构体大小、逃逸分析结果,决定将内存分配在栈上还是堆上。但无论分配位置如何,只要引用还在被使用,这块内存就会被持续保留,不会被复用或篡改。 - 操作系统的内存边界:操作系统不会主动修改用户态进程的内存内容,只有当内存被GC回收、进程退出时,操作系统才会回收这块内存。在内存存活期间,只有你的业务代码或Go运行时的合法操作(如显式修改结构体内容)才会改变内存数据,不存在预期外的写入。
唯一需要注意的是:如果你的代码后续主动修改了这些引用指向的结构体内容,slice中的引用自然会看到变化,但这属于业务逻辑内的操作,不属于“预期外的数据写入”。
内容的提问来源于stack exchange,提问作者moo.duwayne
相关产品推荐
相关产品推荐

