Go语言GC是否会回收仅被goroutine引用的对象?代码场景疑问
Go语言GC与goroutine引用对象的回收问题
直接给结论:Go的垃圾回收器不会回收任何被活跃goroutine引用的对象——哪怕这个对象的唯一引用就在goroutine里,也绝对不会被GC清理掉。
咱们来拆解你给出的代码场景,先把代码整理清晰:
m := map[string]*Object{ "a": obj } go func(obj *Object) { obj.Do() }(m["a"]) delete(m, "a")
这段代码里,当你启动goroutine时,已经把m["a"](也就是obj的指针)作为参数传递给了匿名函数。此时这个goroutine的调用栈里会保存一份obj指针的副本,只要goroutine还在运行(也就是obj.Do()尚未执行完毕),Go的GC在做可达性分析时,就会识别到这个栈中的引用,认定obj是「存活对象」,绝对不会回收它的内存。
哪怕你执行了delete(m, "a")让map不再持有obj的引用也没关系——因为goroutine还攥着这个引用呢,GC绝不会把正在被使用的对象回收掉。
本质上,Go的GC基于可达性分析工作:只要对象能从任何「根节点」(比如全局变量、正在运行的goroutine栈、CPU寄存器中的引用等)到达,就会被标记为存活对象,不会被回收。这里goroutine栈里的obj指针就是一个完全有效的根引用,所以obj在Do()执行完成前都是安全的。
内容的提问来源于stack exchange,提问作者wangjun
相关产品推荐
相关产品推荐

