単純な構造体の非常に大きな配列(1 GB RAM)を割り当てる必要があります。いくつかの割り当て/割り当て解除の後、メモリは断片化され、OutOfMemory例外がスローされます。
これは32ビット未満です。パフォーマンスが低下するため、64ビットは使用したくありません。同じアプリケーションの実行速度は64ビットモードで30%遅くなります。
一度にすべてではなく、チャンクでメモリを割り当てるIList互換配列のいくつかの実装を知っていますか?これにより、メモリの断片化の問題を回避できます。
単純な構造体の非常に大きな配列(1 GB RAM)を割り当てる必要があります。いくつかの割り当て/割り当て解除の後、メモリは断片化され、OutOfMemory例外がスローされます。
これは32ビット未満です。パフォーマンスが低下するため、64ビットは使用したくありません。同じアプリケーションの実行速度は64ビットモードで30%遅くなります。
一度にすべてではなく、チャンクでメモリを割り当てるIList互換配列のいくつかの実装を知っていますか?これにより、メモリの断片化の問題を回避できます。
Josh WilliamsはBigArray<T>
、チャンク配列を使用してブログでクラスを発表しました。
この関連する質問で、より役立つ情報を見つけることができます。
簡単なアドホックな修正は、アプリケーションで3GBスイッチを有効にすることです。そうすることで、アプリケーションで32ビットWindowsのプロセスあたり2GBを超える制限を使用できるようになります。ただし、CLRで許可される最大オブジェクトサイズは2GBのままであることに注意してください。スイッチは、メインの実行可能ファイルのビルド後のアクションを使用して有効にできます。
call "$(DevEnvDir)..\tools\vsvars32.bat"
editbin.exe /LARGEADDRESSAWARE "$(TargetPath)"
配列をインスタンス化するとき、.Netは配列のメモリの連続部分を見つけようとします。32ビットアプリの合計メモリ制限は2Gbであるため、いくつかの割り当てを行った後、そのようなブロックを見つけるのは困難になることがわかります。
のようなものを使用してLinkedList<T>
、連続した割り当ての必要性を回避するか、コードを再構築してこれらのチャンクを小さくすることができます(ただし、完全に安全ではありませんが、これは500Mb配列でも発生しません)。
一方、1つの解決策は、アプリの開始時にこの大きなバッファーを1回だけインスタンス化し、アプリの存続期間中にこの同じスペースを再利用するアルゴリズムを実装することです。
SelectMany
IListの代わりにIEnumerableを使用してデータをプログラムの残りの部分に渡すことができる場合は、 LINQメソッドを使用してこのリストを折りたたむことができます。
そして最後に、カスタムクラスにIListインターフェイスを実装するだけで、内部でいくつかの小さな配列を使用できます。
LinkedListはあなたのために働きますか? http://msdn.microsoft.com/en-us/library/he2s3bh7.aspx