-
-
Notifications
You must be signed in to change notification settings - Fork 502
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ch08gc/barrier: writePointer 疑问 #20
Comments
This comment has been minimized.
This comment has been minimized.
Dijkstra 插入屏障 的图示中:“此时A已经错误的着色,必须结束后的重新扫描”,这里不重新扫描也可以吧?因为可以在下一轮GC,把A回收掉 在上面2个图示中,是不是基于这样一个前提:对象C是栈上的根对象或堆上的从其他灰色对象可达的对象,而A,B都为堆上的对象? 如果Go中目前实现的混合写屏障对被修改对象和被引用对象都标记为灰色,那确实不会出现存活对象丢失的情况了。 |
This comment has been minimized.
This comment has been minimized.
当前轮的黑色对象没有被其他对象引用,在下一轮应该就会是白色对象了,怎么会出现 “最坏情况下可能对象永远都不会被回收掉”?
没有被访问到说明是白色对象,回收器可以从内存分配器知道A的存在吧? |
This comment has been minimized.
This comment has been minimized.
黑色对象已经不可达了,赋值器怎么修改到它呢?
我看Golang源码通过 span 管理对象分配,span 有个 allocBits 负责记录其管理的对象是否分配出去了。释放白色对象,是直接通过 span. allocBits = span.gcmarkBits 实现的。 |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
你好,看了你们的讨论,有几个问题:
|
@yangxikun @PureWhiteWu 前面的回复中由于个人的理解错误,固执的持续回复一些错误的言论,首先对错误的关闭 Issue 表示抱歉,并对提出如此重要的问题表示感谢。 @yangxikun 关于你的提出的质疑,确实是我此前理解的错误,我这里重新给出修改后的描述: 灰色赋值器的 Dijkstra 插入屏障的基本思想是避免满足条件 1: // 灰色赋值器 Dijkstra 插入屏障
func DijkstraWritePointer(slot *unsafe.Pointer, ptr unsafe.Pointer) {
shade(ptr)
*slot = ptr
} 为了防止黑色对象指向白色对象,应该假设 Dijkstra 插入屏障的好处在于可以立刻开始并发标记。但存在两个缺点:
另一种比较经典的写屏障是黑色赋值器的 Yuasa 删除屏障。其基本思想是避免满足条件 2: // 黑色赋值器 Yuasa 屏障
func YuasaWritePointer(slot *unsafe.Pointer, ptr unsafe.Pointer) {
shade(*slot)
*slot = ptr
} 为了防止丢失从灰色对象到白色对象的路径,应该假设 Yuasa 删除屏障的优势则在于不需要标记结束阶段的重新扫描,结束时候能够准确的回收所有需要回收的白色对象。缺陷是 Yuasa 删除屏障会拦截写操作,进而导致波面的退后,产生“冗余”的扫描: Go 在 1.8 的时候为了简化 GC 的流程,同时减少标记终止阶段的重扫成本,将 Dijkstra 插入屏障和 Yuasa 删除屏障进行混合,形成混合写屏障。该屏障提出时的基本思想是:对正在被覆盖的对象进行着色,且如果当前栈未扫描完成,则同样对指针进行着色。
|
@changkun 非常感谢你的回复!让我受益良多!
再次感谢你的分享和解答! |
1a. 这个不是问题,在 On-the-fly Garbage Collection 这篇论文就有明确指出:"new garbage could have been created between an appending phase and the preceding marking phase. We do require: however, that such garbage, existing at the beginning of an appending phase but not identified as such by the collector, will be appended in the next major cycle of the collector. " 1b. 是的,这就是原始的 Dijkstra 写屏障的描述,参见On-the-fly Garbage Collection。Go 的实现只是削弱了其条件 2a. Yuasa 屏障有终止性证明的,具体可以研读其论文:https://core.ac.uk/download/pdf/39218501.pdf 2b. 我目前认为 snapshot 可能一种误解,因为在 Wilson 的论文(Uniprocessor Garbage Collection Techniques https://www.cs.cmu.edu/~fp/courses/15411-f14/misc/wilson94-gc.pdf) 中把插入屏障和删除屏障分别成为增量更新(incremental update)和起始快照(snapshot-at-the-beginning)屏障。 2c. Yuasa 最大的问题在于其精度太低,这一点在 Write Barrier Elision for Concurrent Garbage Collectors 这篇论文里面起始有相关数据说明,可以细读一下。但是我目前认为 Go 选择混合屏障引入的主要目的是为了在未来支持 ROC(当时 ROC 还没有被证明性能不行),以及原提案中提到的并发标记终止(消除 STW)等几个未来的演进方向。
|
十分感谢你抽空进行解答!实在是受益良多! |
hi,想请教您一个问题,Yuasa 删除屏障是保证弱三色不变式,他是在指针删除时候才会触发去执行吗?这样子插入行为(假设我直接在黑色对象插入了白色对象)会直接破坏了强三色不变式。是我哪里理解有问题吗?望指教 |
混合写屏障的算法思想伪代码:
如果当前 goroutine 栈已扫描为黑色,而 ptr 为白色对象,此时如果不对 ptr 着色,是否就误回收了对象?
The text was updated successfully, but these errors were encountered: