go语言基础学习三
2 个 interface 可以比较吗 ?#
可以比较,但是有要求 interface有两个字,V和T,V是值,T是类型。 2 个 interface 相等有以下 2 种情况 一、两个 interface 均等于 nil(此时 V 和 T 都处于 unset 状态) 二、类型 T 相同,且对应的值 V 相等。
2 个 nil 可能不相等吗?#
两个nil只有在类型相同时才相等
func main() {
var p *int = nil
var i interface{} = nil
if p == i {
fmt.Println("Equal")
} else {
fmt.Println("Not Equal")
}
}
//预期:
//Not Equal
简述 Go 语言GC(垃圾回收)的工作原理#
Go1.3采用标记清除法, Go1.5采用三色标记法,Go1.8采用三色标记法+混合写屏障。
标记清除法#
分为两个阶段:标记和清除 标记阶段:从根节点遍历所有可以到底的对象,并将其标记为存活 清除阶段:遍历所有对象,如果未被标记,则将其清除 缺点是需要暂停程序STW(stop the world)
三色标记法#
将对象分为三类:存活但是子对象未扫描、已标记、未标记,分别对应灰色、黑色、白色
过程:
先将所有对象标记为白色,然后把根节点标记为灰色,从灰色节点中取出一个,并开始遍历它的子对象,
将它的子对象放进灰色集合,遍历完成后,将它自己标记为黑色,并将其从灰色集合中移除.这个过程会重复,直到灰色集合为空.
这种方法有一个缺陷,如果对象的引用被用户修改了,那么之前的标记就无效了。
因此Go采用了写屏障技术,当对象新增或者更新会将其着色为灰色
混合写屏障#
插入写屏障#
黑色对象 引用 白色对象 → 把白色变灰色
删除写屏障#
删除一个指向白色对象的引用 → 把白色变灰色
核心设定(栈永远黑):
GC 开始时:并发扫描所有 goroutine 栈,栈上对象全部标黑(不 STW)
GC 期间:栈上新创建的对象直接标黑
结论:整个标记阶段,栈上永远只有黑色对象,没有白色 / 灰色
原创
go-three
本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
评论交流
欢迎留下你的想法