栈上的黑色对象指向堆上的白色对象问题

栈上的黑色对象指向堆上的白色对象问题

曹大:根据强三色不变性,栈上的黑色对象指向堆上的白色对象是不合法的,但是如果这个白色对象堆上没有被其他对象引用,栈上又不会有写屏障,那么这个白色对象岂不是永远不会被标记为灰色或者黑色么?

正在回答 回答被采纳积分+1

登陆购买课程后可参与讨论,去登陆

2回答
Xargin 2021-06-22 14:39:29

课上的这个动画还有一种更复杂的情况,你可以看看:


https://www.figma.com/proto/tSl3CoSWKitJtvIhqLd8Ek/memory-management-and-and-garbage-collection?page-id=201%3A293&node-id=201%3A294&viewport=3552%2C382%2C0.5088089108467102&scaling=contain

Xargin 2021-06-22 14:33:12

栈上的黑指向了堆上的白,

说明这个堆上的白一定是从堆上某条链路断掉的对象:

http://img1.sycdn.imooc.com//climg/60d1838d09ebda4714400872.jpg

比如这个,我们后续让 z 指向 D

http://img1.sycdn.imooc.com//climg/60d183ab0976ca7d14220672.jpg


但是要考虑到 Go 的屏障是混合屏障(包含了删除写屏障的逻辑)

所以堆上的链路在标记过程中断开的话(被 mutator 修改),被断开的那个对象一定会被标灰

所以第二张图这样的情况不会出现,B -> D 断开的时候,D 会被标灰(就是 D 对象的 gcMarkbit = 1 && 进 wbBuf)

正常的应该是这样:

http://img1.sycdn.imooc.com//climg/60d1840c09c446ad10500470.jpg

  • 我的意思是本来就没有B指向D这个情况存在呢?

    2021-06-22 15:06:59
  • Xargin 回复 提问者 weixin_慕设计2382076 #2

    那不可能,对象变黑的时候,一定会把子对象 gcMarkbit 置 1 进队列的,

    三色抽象就是这样玩的

    2021-06-22 15:58:18
  • 提问者 weixin_慕设计2382076 回复 Xargin #3

    这样的情况呢:

    栈上的对象A指向堆上的对象B;

    这时候stw,进行标记,A是灰色;

    然后concurrent mark,A标记为黑色,B标记为灰色;

    这时候异步操作栈上对象A指向堆上对象C,然后又有因为栈上操作没有写屏障,不就会出现么?

    2021-06-22 16:20:38
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师