我一直在努力在我们的应用程序中找到内存泄漏,并且一直在使用pprof工具来了解正在发生的事情。

当我查看堆时,我经常看到以下函数,我不明白为什么(或者如果)它实际上是一个问题。

func CreateClients(raw []byte) bool {

    macs := []string{}
    conn := FormatConn(raw)

    if conn.Ap_Mac != "" {

        var wg sync.WaitGroup
        var array []Client

        c1 := make(chan Client)

        clients := FormatClients(conn)

        wg.Add(len(clients))

        for _, c := range clients {
            go func(d Client) {
                defer wg.Done()
                c1 <- UpdateClients(d)
            }(c)
        }

        go func() {
            defer wg.Done()
            for {
                select {
                case client := <-c1:
                    array = append(array, client)
                    macs = append(macs, client.Client_Mac)
                }
            }
        }()

        wg.Wait()
        // Do some other stuff
    ...
}

UpdateClients函数更新Mongo中的客户端模型。 当它返回时,我需要每个客户端 - 所以我可以用ES索引它,我需要一个mac数组来做其他的东西。

我已经浏览了在线示例,并认为这是循环通道的推荐方法。

我的pprof堆看起来像这样,并在几天内稳步增长:

7.53MB of 9.53MB total (79.00%)
Dropped 234 nodes (cum <= 0.05MB)
Showing top 5 nodes out of 28 (cum >= 1MB)
      flat  flat%   sum%        cum   cum%
       2MB 21.00% 21.00%        2MB 21.00%  strings.Replace
    1.51MB 15.89% 36.89%     1.51MB 15.89%  github.com/PolkaSpots/worker/worker.func·006
    1.51MB 15.87% 52.76%     1.51MB 15.87%  github.com/PolkaSpots/worker/worker.func·008
    1.50MB 15.75% 68.51%     1.50MB 15.75%  newproc_m
       1MB 10.50% 79.00%        1MB 10.50%  gopkg.in/mgo.v2/bson.(*decoder).readStr

是否有更有效/推荐的方法来实现这一目标?

编辑_

正如所建议的那样,我已经改变了循环

    done := make(chan bool)

    go func() {
        for {
            select {
            case client := <-c1:
                array = append(array, client)
                macs = append(macs, client.Client_Mac)
            case <-done:
                return
            }
        }
    }()

    wg.Wait()
    close(done)