多くの byte[] 配列 (それぞれ約 1 ~ 2 MB) を生成し、それらにデータを入力してから、参照を破棄するループがコードに含まれています。そのため、参照は短期間しか保持されていませんが、プライベート ワーキング セットが成長していることがわかります。
ここで、ループ後に大きな配列 (~ 400 MB) を割り当てようとすると、メモリ不足の例外が発生する可能性がありますか? それとも、割り当てによって GC が一時データを収集するように強制されますか?
ありがとう!
多くの byte[] 配列 (それぞれ約 1 ~ 2 MB) を生成し、それらにデータを入力してから、参照を破棄するループがコードに含まれています。そのため、参照は短期間しか保持されていませんが、プライベート ワーキング セットが成長していることがわかります。
ここで、ループ後に大きな配列 (~ 400 MB) を割り当てようとすると、メモリ不足の例外が発生する可能性がありますか? それとも、割り当てによって GC が一時データを収集するように強制されますか?
ありがとう!
1〜2MBのアレイを多数生成することはお勧めできません。メモリ不足の状況を回避しても、パフォーマンスは実際に低下します。ラージオブジェクトヒープに多くの短命のオブジェクトを割り当てることは、現在のGCがうまく処理できない割り当てパターンです。
可能な限りリサイクルすることを強くお勧めします。配列が不要になったら、配列をスローするプールを実装します。そして、最初に割り当てるときに、プールからの要求を満たすことができるかどうかを確認します。そのパターンにより、私のプログラムの1つでパフォーマンスが大幅に向上しました。
フルメモリはGCを強制すると思いますが、管理されていない割り当てがほぼ同時に発生した場合でも、OOMを取得できます。
心配ならいつでも GC.Collect(); を呼べます。ループ後の大きな配列の前に、すべての世代のガベージ コレクションを強制します。ただし、これはかなり遅くなる可能性があるため、時間を気にしない限り、ループ内で実行しないでください (ループには遅すぎますが、1 回限りの処理にはそれほど時間はかかりません)。
これは本当に異なります。ガベージコレクターが時間内に破棄されるかどうかはわかりません。バイト配列を使用すると、かなり安全ですが、メソッドを使用せずにそれらを多用すると、ほとんどのオブジェクトが破棄されるのが遅すぎますdispose()
。
これにより、すべての参照を破棄した場合でも、メモリ不足の例外が発生します。
問題が発生した場合は、試してみることができますがGC.Collect(0);
、これは通常はお勧めできません。