猿问

Go 保证地址不变吗?

给定一个对象obj是否有保证

uintptr(unsafe.Pointer(&obj))

无论何时调用它都会始终评估为相同的值?

当然,Go 保证如果您将两个指针指向同一个对象,它们将始终比较相等。尽管实现可能会在内存中移动对象并透明地更新指向它的所有指针。

如果您考虑像Mark-and-Compact这样的垃圾收集策略,这会很有趣。是否允许实现者使用这样的垃圾收集策略?


繁花如伊
浏览 325回答 3
3回答

杨魅力

没有这样的保证,完全可以实现移动收集器。事实上,虽然垃圾收集器今天不移动堆对象,但在 Go 1.3 中堆栈可以在需要增长时移动,因此完全有可能var obj intfmt.Println(uintptr(unsafe.Pointer(&obj)))bigFunc()fmt.Println(uintptr(unsafe.Pointer(&obj)))将打印两个不同的指针,因为 bigFunc 增加了堆栈,导致 obj 和堆栈上的所有其他内容移动。

汪汪一只猫

规范中没有任何内容可以保证这一点,可能是为了允许该语言的实现在未来使用压缩垃圾收集器。在这个 golang-nuts 线程中,一位开发人员建议如果unsafe.Pointer值固定在内存中,则可以进行压缩 GC ,但这不能扩展到所有unitptr值。对于当前的 Go 运行时,我相信这是真的,但依赖它仍然是未定义的行为。但有一些警告:如果obj是零大小类型,则表达式的值可能不是唯一的,如规范中所述。在程序的整个生命周期中,一个特定的uintptr值可能会引用不同的对象。

繁星淼淼

没有绝对的保证。特别是如果 Go 为其标记和清除垃圾收集器添加了压缩。如果需要,任何垃圾收集器都会更新存储在指针类型和类型中的地址unsafe.Pointer。uintptr垃圾收集器不会更新以类型存储为无符号整数的地址。该uintptr类型不是指针类型,而是整数类型。数字类型uintptr 一个足以存储指针值的未解释位的无符号整数将 unsafe.Pointers 转换为 uintptr指针应该一直保存在 unsafe.Pointers - 而不是 uintptrs - 中。拉斯对于你的例子,uintptr(unsafe.Pointer(&obj))你有一个无符号整数,而不是地址。
随时随地看视频慕课网APP

相关分类

Go
我要回答