3

プログラムのプロファイリング中に、大量の byte[] がメモリ内で動かなくなっていることに気付きました。掘り下げたところ、次のような方法で作成されたインスタンスの大部分が見つかりました。

public byte[] CreateBytes(byte[] bytes)
{
    using (var start = new MemoryStream()) 
    {
        using (var memStr = new MemoryStream(bytes))
        {
            //do stuff
            return start.ToArray();
        }
    }
}

返された byte[] は他のメソッドに渡され、MemoryStream別の using ブロック内から別のメソッドを作成する際に使用されます。

using (var uncompressedStream = new MemoryStream(uncompressedData))
{
    using (var compressedStream = new MemoryStream())
    {
        //Do some compression
    }
}

myObject.Bytes = uncompressedData;
uncompressedData = null;

return myObject;

(uncompressedDataは CreateBytes() から返される値です)。

私の質問は、byte[] がクリーンアップされるのはいつですか? 特にnullに設定する必要がありますか?もしそうなら、どこで? 2 番目の using ブロックの後、私はそれを必要としなくなりましたが、単純に言えば、それがuncompressedData = null;メモリを再利用するかどうかはわかりません。

using ステートメントがバイトを破棄したと思っていましたCreateBytes(byte[] bytes)が、参照を返しているため、破棄を延期および/または放棄しますか?

編集: 別のコード行を追加しました。uncompressedBtyes を別のオブジェクトに保存しているので、uncompressedData を null に設定しても無意味であり、byte[] はその限りmyObject(またはmyObject.Bytesnull に設定されるまで) 存続します。正しいですか?

4

4 に答える 4

5

次の 2 つの条件が両方とも満たされると、byte[] がクリーンアップされます。

  • そのメモリ ブロックへの参照はありません
  • ガベージ コレクターは、そのメモリ ブロックを収集することを決定します。

GC は、さまざまな要因に基づいて非決定的な時間に実行されます。

于 2012-08-29T20:53:42.920 に答える
1

バイト配列は、メモリ内の他のマネージド オブジェクトと同様に、ルート参照からアクセスできなくなるとすぐにガベージ コレクションの対象になります。GC を信頼して、それがいつ発生したかを認識し、適切なオブジェクトのクリーンアップを実際に実行する時間をインテリジェントにスケジュールできます。クリーンアップの対象となるオブジェクトが実際にいつクリーンアップされるかについて心配する必要はありません。GC の方がよくわかっている可能性があります。

于 2012-08-29T20:55:10.590 に答える
0

エリックの回答に加えて:

それ以上は必要ないと確信したらbyte[]、それに割り当てnullます。

これは、メモリがすぐに再利用されることを保証するものではなく、後で再利用されることも保証しませんこれは、コレクションの対象としてそれを識別するのに役立つ 方法です。GC

于 2012-08-29T20:55:48.497 に答える
0

このステートメントは、返される配列usingとはまったく関係ありません。byte

MemoryStream廃棄可能であり、そのオブジェクトの廃棄はusingステートメントが管理しているものです (廃棄はガベージ コレクションと同じではありませんが、通常はガベージ コレクションの前身であることに注意してください)。

を呼び出すとToArray()、使い捨てではない新しいものを作成しています。範囲外になると、ガベージ コレクターによって不確定な時間にクリーンアップされます (これは通常、適切に最適化されたプロセスです)。

于 2012-08-29T20:57:35.897 に答える