Go GC:不安全,指针递归地跟随?

vfh0ocws  于 2023-09-28  发布在  Go
关注(0)|答案(1)|浏览(97)

我正在使用用户定义的数据结构,自己管理内存布局,但利用Go GC。我遇到了一个bug,过去两天我都没弄清楚:一些变量随机地改变值。
关闭GC后,问题消失。似乎内存被重用,因此值发生了变化。
我知道的是:

  • Go GC跟踪unsafe.Pointers,所以我总是将指针存储为unsafe. Pointers。
  • Go跟踪关于值的元数据“在一边”,以了解哪些是普通值,哪些是非普通值。unsafe.Pointers.[ source ]

但是GC如何知道一个值在哪里结束呢?
请参见以下内存段示例,其中每个字母是一个单词(64位):

[A, b, c, D, e, F]

大写字母是不安全的。指针,小写是普通值。我有一个指向上面的unsafe.指针,所以GC知道要保持从A开始的值。但是它需要遵循unsafe.指针DF吗?这取决于从A开始的值在哪里结束。
它怎么知道的?

jbose2ul

jbose2ul1#

回答我自己的问题。(你只需要努力阐明问题,很快就能找到答案。)

是,不安全,指针被跟踪

值存储在一个(目前有67个)跨度类中,每个跨度类都有一个固定的大小,因此值的位置决定了它在GC中的长度。(任何剩余的字节都可能被归零。)
Source

调试

  • GODEBUG上设置clobberfree=1 env var以用垃圾数据覆盖释放的内存段(例如:运行GODEBUG=clobberfree=1 go test)。这是对我来说最有用的调试工具,与通过runtime.GC()强制GC结合使用。还有更方便的选项:环境变量。
  • 使用runtime.SetFinalizer()查找意外释放的对象

相关问题