我要做什么: 我试图通过三个阶段来理解/构建一个go管道。阶段1向通道A写入。阶段2具有多个go例程。每个go例程都从通道A读取,执行一些操作并将结果写入通道Bn(通道B1,B2..Bn)。第3阶段创建了n(=第2阶段中的通道总数)go例程,每个go例程从第2阶段的一个Channel中读取。它基于https://blog.golang.org/pipelines
中描述的有限并行性问题: 管道按预期工作正常,操作在go例程之间分配。但是当我进行逃逸分析时,发现从一个阶段发送到另一个阶段的通道参数被报告为“泄漏参数”。
代码段: 为简单起见,我发布的代码显示第1阶段通道的创建,第2阶段打印从第1阶段的通道读取的值。
$.ajax('/pages/home', {
type: "POST",
data: 'impressions=' + impressions,
dataType: 'script'
})
这是逃生分析结果
package main
import "fmt"
func createStageOne(numOfJobs int) <-chan int {
stageOneChannel := make(chan int)
go func(nJobs int) {
for i := 0; i < nJobs; i++ {
stageOneChannel <- i
}
close(stageOneChannel)
}(numOfJobs)
return stageOneChannel
} // stageOneChannel closes and go routine exits once nJobs are completed
func createStageTwo(in <-chan int, completionFlag chan struct{}) {
go func() {
for n := range in {
fmt.Println("Received from stage 1 channel ", n)
}
completionFlag <- struct{}{}
}()
}// Comes out of for loop when stage 1 channel closes and go routine also exits
func main() {
numOfJobs := 10
stageOneChannel := createStageOne(numOfJobs)
done := make(chan struct{})
createStageTwo(stageOneChannel, done)
<-done
}
为什么逃逸分析在 in 和 completionFlag 标志上报告泄漏参数?
答案 0 :(得分:4)
所讨论的参数是引用类型的通道。它们被捕获在createStageTwo()中创建的闭包中,并且可以在createStageTwo()返回时继续在该闭包的go例程中使用。因此,它们被信号通知为泄漏参数。如果不是,那么它们将被放置在堆栈上,并且在main()完成它们后变为无效。
这并不意味着您有问题。逃逸分析无法检测到资源泄漏,大多数人永远都不需要使用它。 (对于在您不期望的地方放置一些GC堆上的性能问题,这很有用。)
(对不起@Volker,我最初在评论中张贴了我的答案,这使您的问题无处解决。)