3 回答
TA贡献1811条经验 获得超6个赞
没有这样的保证,完全可以实现移动收集器。
事实上,虽然垃圾收集器今天不移动堆对象,但在 Go 1.3 中堆栈可以在需要增长时移动,因此完全有可能
var obj int
fmt.Println(uintptr(unsafe.Pointer(&obj)))
bigFunc()
fmt.Println(uintptr(unsafe.Pointer(&obj)))
将打印两个不同的指针,因为 bigFunc 增加了堆栈,导致 obj 和堆栈上的所有其他内容移动。
TA贡献1898条经验 获得超8个赞
规范中没有任何内容可以保证这一点,可能是为了允许该语言的实现在未来使用压缩垃圾收集器。在这个 golang-nuts 线程中,一位开发人员建议如果unsafe.Pointer
值固定在内存中,则可以进行压缩 GC ,但这不能扩展到所有unitptr
值。
对于当前的 Go 运行时,我相信这是真的,但依赖它仍然是未定义的行为。但有一些警告:
如果
obj
是零大小类型,则表达式的值可能不是唯一的,如规范中所述。在程序的整个生命周期中,一个特定的
uintptr
值可能会引用不同的对象。
TA贡献1775条经验 获得超11个赞
没有绝对的保证。特别是如果 Go 为其标记和清除垃圾收集器添加了压缩。
如果需要,任何垃圾收集器都会更新存储在指针类型和类型中的地址unsafe.Pointer
。uintptr
垃圾收集器不会更新以类型存储为无符号整数的地址。该uintptr
类型不是指针类型,而是整数类型。
数字类型
uintptr
一个足以存储指针值的未解释位的无符号整数将 unsafe.Pointers 转换为 uintptr
指针应该一直保存在 unsafe.Pointers - 而不是 uintptrs - 中。
拉斯
对于你的例子,
uintptr(unsafe.Pointer(&obj))
你有一个无符号整数,而不是地址。
- 3 回答
- 0 关注
- 324 浏览
添加回答
举报