第 120 期 2021-10-28 垃圾回收与Go实现
YouTube
垃圾回收是一门古老的科学,也是现在高级语言的标配。作为运行时最复杂的模块,其背后的工作原理、设计哲学、调试手段是什么?在本小节中将为你解开垃圾回收背后的秘密
大纲
- 什么是垃圾回收
- 为什么需要垃圾回收
- 经典的垃圾回收策略
- Go垃圾回收的选择与历史演进
- Go垃圾回收生命周期完全解读
- Go垃圾回收调试手段
分享者自我介绍
郑建勋,《Go语言底层原理剖析》作者,Go语言垃圾回收 Contributor . 互联网内卷王者. 公众号gopher梦工厂作者
计划分享时间
2021-10-28 21:00:00 UTC+8
参考资料
《Go语言底层原理剖析》
《The Garbage Collection Handbook》
《垃圾回收的算法与实现》
《VIDEO Garbage Collection Algorithms》By Dmitry Soshnikov
Getting to Go: The Journey of Go's Garbage Collector - The Go Programming Language
GC scanning of stacks - Google Docs
pdf
go夜读—垃圾回收.pdf (8.2 MB)
3 个赞
您好,我有一个疑惑,在GC的扫描与标记阶段会遍历Goroutine的栈,在这个过程中可能会碰到所遍历的栈内对象是普通对象或者指针的情况,请问是如何判断该对象是普通值类型还是指针类型,我理解这决定是否还要继续深入扫描的关键点。
我查阅了不少资料,但是关于这方面的讲述的很少,仅有这篇文章的 Identifying Pointers 小节还略有提及: Lecture 25: Garbage Collection,但是对于Go在代码层面是如何实现这层判断的,我仍然不得所知,也许是编译器做了,又或许是GC本身可以支持判断?此外,我还阅读了1.15版本的部分GC源码scanstack
(/usr/local/go/src/runtime/mgcmark.go:790),在这里会调用scanblock()
,该函数中有一个段逻辑是判断p是否为零(如下):
p := *(*uintptr)(unsafe.Pointer(b + i))
if p != 0 {
if obj, span, objIndex := findObject(p, b, i); obj != 0 {
greyobject(obj, b, i, span, gcw, objIndex)
} else if stk != nil && p >= stk.stack.lo && p < stk.stack.hi {
stk.putPtr(p, false)
}
}
也许这会判断是否为指针?
----------------------------更新----------------------------
我买了您的书看了一下 20.3.4 节栈扫描,已经解释了我上面的问题,是编译器向运行时提供位图以表明是否为指针,在该节您提到了一个不再被使用的对象,不需要再扫描了,从代码层面确实比较好理解
func foo(){
t := T{}
t.a = 2
bar()
}
t 对象在调用 bar()
时已经没有被使用了,但是运行时如何在进行栈扫描时确定该对象没有被使用了,请也是有类似位图这样的标记吗?
1 个赞