为什么 Go 通道在函数完成后仍然不会被垃圾回收和关闭?

huangapple go评论160阅读模式
英文:

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 (
	    &quot;fmt&quot;

    )

    func main(){
    	leak()
    	for{}
      }

func leak() {
    ch := make(chan int)

    go func() {
		fmt.Println(&quot;i am stuck here&quot;)
        val := &lt;-ch
        fmt.Println(&quot;We received a value:&quot;, val)
		
    }()
	fmt.Println(&quot;i have finished my fuction&quot;)
}

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)

huangapple
  • 本文由 发表于 2021年3月6日 21:28:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/66506155.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定