2016-05-23 2 views
2

[]バイトのcompressedbytesに圧縮されたASCIIテキストのバイトを受け取りました。私が直面している問題は、次の手順では、関数が終わりに達しても解放されず、プログラムの実行時に占領されたままの大量のメモリを占有するということです。バイトで占有されたメモリを解放できません。バッファー

b := bytes.NewReader(compressedbytes) 
    r, err := zlib.NewReader(b) 
    if err != nil { 
     panic(err) 
    } 
    cleartext, err = ioutil.ReadAll(r) 
    if err != nil { 
     panic(err) 
    } 

私が使用しているタイプがbytes.Bufferであり、このタイプはReset()Truncate()機能を持っていますが、それらのどれもが一度占有されているメモリを解放することができないことに気づきました。

リセットは、バッファが空にリセットされますが、それは今後の書き込みで使用するための基盤となるストレージを保持し、次の

documentationReset()の状態。リセットは切り捨て(0)と同じです。

バッファを解除して再度メモリを解放するにはどうすればよいですか? 私のプログラムは、実行中に約2MBのメモリが必要です。 zlib圧縮された文字列をインポートすると、プログラムには200 MBのメモリが必要です。

ありがとうございました。

===更新

私も解凍のために別の関数を作成し、プログラムが成功せず、その関数から戻った後runtime.GC()を使って手動でガベージコレクタを呼び出します。

// unpack decompresses zlib compressed bytes 
func unpack(packedData []byte) []byte { 
    b := bytes.NewReader(packedData) 
    r, err := zlib.NewReader(b) 
    if err != nil { 
     panic(err) 
    } 
    cleartext, err := ioutil.ReadAll(r) 
    if err != nil { 
     panic(err) 
    } 
    r.Close() 
    return cleartext 
} 
+0

何b.WriteTo(os.stdout)を使用してバッファを排水については? – khrm

+1

どのようにメモリ使用量を測定していますか? – elithrar

+0

私は、この文の前後に一時停止(ユーザ入力を待っている)を置いて、プロセスメモリがその間で拡大するのを見ます。 SysInternals ProcessExplorerの「WorkingSetSize」列と「PrivateBytes」列でチェックします。 – JohnGalt

答えて

17

いくつかの事項をクリアしてください。ゴーは、(あなたはまだ「到達可能」としてカウント変数への別のポインタを、持っている場合)、これらの変数が到達不能になったときに、メモリの変数によって割り当てられ、使用を自動的にガベージコレクタによって解放されることを意味し、ごみ収集の言語です。

解放されたメモリは、OSに返されるわけではありません。解放されたメモリとは、メモリが再利用可能であり、必要があれば別の変数に再利用できることを意味します。オペレーティングシステムからは、変数が到達不能になり、ガーベジコレクタがこれを検出してメモリが解放されたため、すぐにメモリが減少することはありません。 (通常は約5分である)いくつかの時間のために使用されていない場合

のGoランタイムは、しかし、OSにメモリを返します。この期間中にメモリ使用量が増加した場合(オプションで再び縮小される場合)、メモリはOSに返されない可能性が非常に高いです。あなたはいくつかの時間を待ってから再度メモリを割り当てられない場合

、解放されたメモリは、最終的にはOSに返されます(当然すべてではないが、未使用の「大きな塊」になります)。あなたが起こるために、このために待つことができない場合は、この動作を強制的にdebug.FreeOSMemory()を呼び出すことができます:

FreeOSMemoryは、可能な限り、オペレーティング・システムにできるだけ多くのメモリを返却しようとする試みが続いガベージコレクションを強制します。 (これが呼び出されなくても、ランタイムはバックグラウンドタスクでオペレーティングシステムに徐々にメモリを返します。)

古いが、本当に有益な質問+回答のこの種のチェックアウト:

Go 1.3 Garbage collector not releasing server memory back to system

+0

ありがとうございました。 – JohnGalt

2

これはもう何も参照しないときにリリースされます.GoにはまともなGCがあります。

+0

私は別の関数にすべてを入れても、runtime.GC()によって関数から戻った後でガベージコレクタを呼び出すと、ガベージコレクタによってクリーンアップされません。 – JohnGalt

+0

@JohnGalt:メモリを解放するガベージコレクタの仕事ではありません。ヒープスカベンジャーは、実行時にOSに空きメモリを戻すことがありますが、それはGCとは関係ありません。 – JimB

関連する問題