关于GO语言GC的疑问

159 阅读2分钟

go: GC时写屏障与栈的引用变化 - 云+社区 - 腾讯云 (tencent.com) 文章指出

设想下面的场景:

  1. 故事发生在两个goroutine上
  2. 栈1已被扫黑,它下面的对象都是灰色
  3. 栈2还未被扫黑,所以它引用的D可能是白色。
  4. 在GC之时,解除ref2,并且将ref指向D。
  5. 因为引用改变都发生在栈上,不会触发屏障。所以D被回收?

因为这是一个伪命题:

  1. 对栈的操作是原子操作,要么栈全灰,要么全黑。
  2. 已被扫黑的栈,引用的堆上的对象至少是灰色。(比如C对象)。所以不可能发生同栈下引用改变会影响GC的问题。
  3. 不可能发生上述的跨栈的引用。因为“对象不是从天上掉下来的”。假设A对象可以与D对象建立引用,只有可能A也直接间接持有B对象。否则没有路径可以建立这样的引用。然而,因为Go的逃逸分析,B对象被外部引用,不可能存在于栈上。所以B一定是堆上的对象。

对于第三点“不可能发生上述的跨栈的引用。因为“对象不是从天上掉下来的”。假设A对象可以与D对象建立引用,只有可能A也直接间接持有B对象。否则没有路径可以建立这样的引用。然而,因为Go的逃逸分析,B对象被外部引用,不可能存在于栈上。所以B一定是堆上的对象。” 有点疑问。

在go中可不可以通过直接向指针中设置地址的形式进行由A直接指向D。

比如最开始关系是B->D 拿到D的内存地址,通过二进制形式写入到某个文件中,B释放D的引用后,A读取二进制文件中的内容直接创建一个指针值设置为D的内存地址。这样是不是就可以实现跨栈的引用,让D变成“从天上掉下来的对象”