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.)

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

报告相同问题?

悬赏问题

  • ¥60 求一个简单的网页(标签-安全|关键词-上传)
  • ¥35 lstm时间序列共享单车预测,loss值优化,参数优化算法
  • ¥15 基于卷积神经网络的声纹识别
  • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
  • ¥100 为什么这个恒流源电路不能恒流?
  • ¥15 有偿求跨组件数据流路径图
  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值
  • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
  • ¥15 CSAPPattacklab
  • ¥15 一直显示正在等待HID—ISP