dtxpz8785 2017-02-13 19:51
浏览 112

为什么这个golang程序会造成内存泄漏?

I am trying to understand concurrency and goroutines, and had a couple questions about the following experimental code:

  1. Why does it create a memory leak? I thought that a return at the end of the goroutine would allow memory associated with it to get cleaned up.
  2. Why do my loops almost never reach 999? In fact, when I output to a file and study the output, I notice that it rarely prints integers in double digits; the first time it prints "99" is line 2461, and for "999" line 6120. This behavior is unexpected to me, which clearly means I don't really understand what is going on with goroutine scheduling.

Disclaimer:

Be careful running the code below, it can crash your system if you don't stop it after a few seconds!

CODE

package main

import (
    "fmt"
    "sync"
)

func main() {
  var wg sync.WaitGroup
    for {
      // spawn four worker goroutines
      spawnWorkers(4, wg)
      // wait for the workers to finish
      wg.Wait()
    }
}

func spawnWorkers(max int, wg sync.WaitGroup) {
  for n := 0; n < max; n++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            f(n)
          return
        }()
    }   
}

func f(n int) {
    for i := 0; i < 1000; i++ {
      fmt.Println(n, ":", i)
    }
}
  • 写回答

1条回答 默认 最新

  • doushi6947 2017-02-13 20:32
    关注

    Thanks to Tim Cooper, JimB, and Greg for their helpful comments. The corrected version of the code is posted below for reference.

    The two fixes were to pass in the WaitGroup by reference, which fixed the memory leak, and to pass n correctly into the anonymous goroutine, and

    package main
    
    import (
        "fmt"
        "sync"
    )
    
    func main() {
      var wg sync.WaitGroup
        for {
          // spawn four worker goroutines
          spawnWorkers(4,&wg)
          // wait for the workers to finish
          wg.Wait()
        }
    }
    
    func spawnWorkers(max int, wg *sync.WaitGroup) {
      for n := 0; n < max; n++ {
            wg.Add(1)
            go func(n int) {
                defer wg.Done()
                f(n)
              return
            }(n)
        }   
    }
    
    func f(n int) {
        for i := 0; i < 1000; i++ {
          fmt.Println(n, ":", i)
        }
    }
    
    评论

报告相同问题?

悬赏问题

  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值
  • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
  • ¥15 CSAPPattacklab
  • ¥15 一直显示正在等待HID—ISP
  • ¥15 Python turtle 画图
  • ¥15 关于大棚监测的pcb板设计
  • ¥15 stm32开发clion时遇到的编译问题
  • ¥15 lna设计 源简并电感型共源放大器
  • ¥15 如何用Labview在myRIO上做LCD显示?(语言-开发语言)
  • ¥15 Vue3地图和异步函数使用