垃圾收集器会收集永远不会继续的Go例程吗?

fuz*_*fuz 9 memory-leaks go goroutine

请考虑以下代码作为简化示例:

func printer(c <-chan int) {
    for {
        fmt.Print(<-c)
    }
}

func provide() {
    c := make(chan int)

    go printer(c)

    for i := 1; i <= 100; i++ {
        c <- i
    }
}
Run Code Online (Sandbox Code Playgroud)

该函数provide创建一个printer打印数据provide生成的go例程.

我的问题是,在provide返回并printer在空信道上开始阻塞后会发生什么.go例程是否会泄漏,因为没有进一步的引用c或者垃圾收集器是否会抓住这种情况并且同时处理go例程和c

如果确实是这种代码导致内存泄漏的情况,我可以采取什么策略来防止这种内存泄漏?

zzz*_*zzz 10

关闭频道.从封闭通道读取总是成功,返回相应的零值.可选的第二个布尔值返回值表示第一个值的有效性.

接收运营商:

表单赋值或初始化中使用的接收表达式

x, ok = <-ch
x, ok := <-ch
var x, ok = <-ch
Run Code Online (Sandbox Code Playgroud)

产生类型的额外结果,bool报告通信是否成功.的值ok,如果接收到的值通过一个成功的发送操作被传送到信道,或者如果其为产生,因为信道被关闭,空零值是真实的.

func printer(c <-chan int) {
        for {
                v, ok := <-c
                if !ok { // chan closed
                        return
                }

                // v is valid
                fmt.Println(v)
        }
}

func provide() {
        c := make(chan int)

        go printer(c)

        for i := 1; i <= 100; i++ {
                c <- i
        }
        close(c)
}
Run Code Online (Sandbox Code Playgroud)

  • 使用打印机goroutine中的range子句将避免ok检查 - > for v:= range c {fmt.Println(v)} (3认同)