英文:
why go channel is not garbage collected and closed even after completion of function
问题
package main
import (
"fmt"
)
func main() {
leak()
for {}
}
func leak() {
ch := make(chan int)
go func() {
fmt.Println("我被卡在这里")
val := <-ch
fmt.Println("我们收到了一个值:", val)
}()
fmt.Println("我已经完成了我的函数")
}
在这段代码中,ch
通道是在leak()
函数内部定义的。根据我的理解,当leak
函数执行完毕并返回后,ch
应该超出了作用域并被垃圾回收,但是它的goroutine却无限期地等待从通道中接收值。实际上发生了什么?
英文:
package main
import (
"fmt"
)
func main(){
leak()
for{}
}
func leak() {
ch := make(chan int)
go func() {
fmt.Println("i am stuck here")
val := <-ch
fmt.Println("We received a value:", val)
}()
fmt.Println("i have finished my fuction")
}
here since my channel "ch" is defined inside leak() function, so my understanding is after leak function is finished and returned, "ch" will be out of scope and should be garbage collected, but its open and go-routine waits indefinitely for value to receive from it,
what is actually ahappening??
答案1
得分: 2
在leak()
函数返回之后,仍然有一个引用到通道的goroutine存在,这个goroutine是在leak()
函数内部创建的。这个goroutine仍然在运行,并且它在等待从通道接收数据时被阻塞。由于存在引用,它无法被垃圾回收。
需要明确的是,垃圾回收并不是关于“它超出了作用域”,而是关于“没有对它的引用”。在这种情况下,通道仍然有一个引用(在生成的goroutine中)。
英文:
After the leak()
func returns, there's still a goroutine with a reference to the channel - the one you created inside of leak()
. That goroutine is still running, and it is blocked on the receive from the channel. Because there's a reference, it can't be garbage collected.
To be clear, garbage collection is not about "it's out of scope", but rather "there are no references to it". In this case, there's still a reference to the channel (in the spawned goroutine)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论