将以下代码视为一个简化示例:
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
}
}
provide
函数创建了一个 go 例程 printer
,用于打印 provide
生成的数据。
我的问题是,在 provide
返回并且 printer
开始阻塞空 channel 后会发生什么。 go 例程是否会泄漏,因为没有进一步引用 c
还是垃圾收集器会捕获这种情况并处理 go 例程和 c
?
如果确实是这种代码导致内存泄漏,我可以采取什么策略来防止这种内存泄漏的发生?
最佳答案
关闭 channel 。从关闭的 channel 读取始终成功,并返回相应的零值。可选的第二个 bool 返回值表示第一个值的有效性。
A receive expression used in an assignment or initialization of the form
x, ok = <-ch
x, ok := <-ch
var x, ok = <-ch
yields an additional result of type
bool
reporting whether the communication succeeded. The value ofok
is true if the value received was delivered by a successful send operation to the channel, or false if it is a zero value generated because the channel is closed and empty.
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)
}
关于memory-leaks - 垃圾收集器会收集永远不会继续的 Go 例程吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16591117/