转义分析显示通道为泄漏参数

时间:2019-02-11 02:43:32

标签: go

我要做什么: 我试图通过三个阶段来理解/构建一个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 标志上报告泄漏参数?

1 个答案:

答案 0 :(得分:4)

所讨论的参数是引用类型的通道。它们被捕获在createStageTwo()中创建的闭包中,并且可以在createStageTwo()返回时继续在该闭包的go例程中使用。因此,它们被信号通知为泄漏参数。如果不是,那么它们将被放置在堆栈上,并且在main()完成它们后变为无效。

这并不意味着您有问题。逃逸分析无法检测到资源泄漏,大多数人永远都不需要使用它。 (对于在您不期望的地方放置一些GC堆上的性能问题,这很有用。)

(对不起@Volker,我最初在评论中张贴了我的答案,这使您的问题无处解决。)