dpw30157 2019-02-11 02:43
浏览 27
已采纳

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

What I'm trying to do: I'm trying to understand/build a go pipeline with three stages. Stage 1 writes to channel A. Stage 2 has multiple go routines. Each go routine reads from Channel A, performs some operation and writes result to Channel Bn(Channel B1, B2..Bn). Stage 3 has creates n(=total number of Channels in Stage 2) go routines, each go routine reads from one Channel from stage 2. It is based on bounded parallelism described in https://blog.golang.org/pipelines

Issue: The pipeline works fine as expected, the operation is distributed among go routines. But when I did an escape analysis and found that channel parameter sent from one stage to another is reported as "leaking param".

Code snippet: For simplicity, I'm posting code that shows stage 1 channel creation, and a stage 2 that prints value read from stage channel 1.

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
}

Here is the escape analysis result

$ go build -gcflags "-m -l"
# concurrentHTTP/stackoverflow
./pipeline.go:7:5: func literal escapes to heap
./pipeline.go:7:5: func literal escapes to heap
./pipeline.go:6:25: make(chan int) escapes to heap
./pipeline.go:17:5: func literal escapes to heap
./pipeline.go:17:5: func literal escapes to heap
./pipeline.go:16:21: leaking param: in
./pipeline.go:16:36: leaking param: completionFlag
./pipeline.go:19:16: "Received from stage 1 channel " escapes to heap
./pipeline.go:19:16: n escapes to heap
./pipeline.go:19:15: createStageTwo.func1 ... argument does not escape
./pipeline.go:29:14: make(chan struct {}) escapes to heap

Why is escape analysis reporting leaking param on in and completionFlag flag?

  • 写回答

1条回答 默认 最新

  • doupai8533 2019-02-11 03:40
    关注

    The parameters in question are channels which are reference types. They are captured within the closure created in createStageTwo() and can continue to be used in the go routine for that closure when createStageTwo() returns. Hence they are signaled as leaking parameters. If they were not then they would be placed on the stack and become invalid when main() finished with them.

    This does not mean you have a problem. Escape analysis is not there to detect resource leaks and most people would never need to use it. (It can be useful for performance problems where something is placed on the GC heap which you don't expect.)

    (Sorry @Volker I originally posted my answer in the comments which left your question hanging.)

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 微带串馈天线阵列每个阵元宽度计算
  • ¥15 关于无人驾驶的航向角
  • ¥15 keil的map文件中Image component sizes各项意思
  • ¥30 BC260Y用MQTT向阿里云发布主题消息一直错误
  • ¥20 求个正点原子stm32f407开发版的贪吃蛇游戏
  • ¥15 划分vlan后,链路不通了?
  • ¥20 求各位懂行的人,注册表能不能看到usb使用得具体信息,干了什么,传输了什么数据
  • ¥15 Vue3 大型图片数据拖动排序
  • ¥15 Centos / PETGEM
  • ¥15 划分vlan后不通了