1

私は記憶が増え続けるプログラムを持っています。それがメモリリークなのか、それとも単にバッファが増え続けるのかはわかりません。

問題の切り分けに成功しましたが、それでも問題を見つけることができません。

奇妙な振る舞いがあります。圧縮部分を削除すると、リークがなくなります。だから私はそれがそこにあると思います。しかし、スイッチのchanTestを含む句を(のみ)削除すると、リークもなくなります。誰かが問題を確認して、なぜそれがそのような振る舞いをしているのか説明してもらえますか?go1.0.3を使用しています

ありがとう!

プログラムは次のとおりです:(100msごとにダミーデータを圧縮します)

package main

import (
    "bytes"
    "compress/zlib"
    "fmt"
    "time"
)

func main() {
    timeOut := time.NewTicker(100 * time.Millisecond)
    chanTest := make(chan int32)

    for {       
        L: for {  // timer part
            select {
                case resp := <- chanTest: // strange clause
                    fmt.Println("received stuff", resp)
                case <-timeOut.C:
                    fmt.Println("break")
                    break L
                }
           }
        timeOut = time.NewTicker(100 * time.Millisecond)

        // compression part
        data := []byte{1, 2, 3, 4, 5, 6, 7}
        var b bytes.Buffer
        w := zlib.NewWriter(&b)
        w.Write(data)
        w.Close()

        b.Reset()
    }
}
4

2 に答える 2

3

元のティッカーを呼び出さずに、ループ内で新しいティッカーを開始しています.Stop()。ティッカーは間隔を置いて実行されるため、複数のティッカーが同時に実行され続けることになります。

.Stop()前のものを停止するための呼び出しは、技術的には機能します。

timeOut.Stop()
timeOut = time.NewTicker(100 * time.Millisecond)

...しかし、その目的を無効にしているようです。代わりに、ループ内で新しいティッカーを作成しないでください。元のティッカーは引き続き実行されます。

// timeOut = time.NewTicker(100 * time.Millisecond) // not needed
于 2013-02-05T17:08:21.853 に答える
2

2013年2月25日より新しいgolangチップ(リビジョン1c50db40d078)でこの問題の修正があります。hg pull; hg updateGoのソースコードを更新してGoディストリビューションを再コンパイルするために実行すると、メモリ消費の問題は解消されます。

ただし、これだけではプログラムは正しくなりません。異常に高いメモリ消費を修正するだけです。正しい実装はを呼び出す必要がありますtimeout.Stop()

于 2013-02-06T07:43:59.077 に答える