5

非常に大きなバイトの「キューブ」を作成しようとしているアプリがあります。3 次元配列 (~1000x1000x500) は、関心のあるすべての値を保存しますが、メモリの問題から抜け出しています。これは予期されていたことですが、私が受け取ったさまざまな OOM メッセージの動作は非常に混乱しています。初め:

Foo[,,] foo1 = new Foo[1000, 1000, 500];

OOM エラーで失敗しますが、これは起こりません:
Foo[,,] foo1 = new Foo[250, 1000, 500];
Foo[,,] foo2 = new Foo[250, 1000, 500];
Foo[,,] foo3 = new Foo[250, 1000, 500];
Foo[,,] foo4 = new Foo[250, 1000, 500];

これら 2 つのコード セットは、本質的に同じ量のメモリを消費するべきではありませんか?

また、最初は ~1.5GB が消費されたときにエラー メッセージが表示されていましたが、64 ビット アプリケーションに切り替えることで、失敗する前により多くのメモリを使用できるようになると思いました。

スタック スペースの制限に達していますか? もしそうなら、スタック上に (単一のエンティティとして) 存在する必要なしに、この構造をヒープ上で完全にインスタンス化するにはどうすればよいでしょうか?

前もって感謝します - 誰もがこの振る舞いに打ち勝つことができる光を楽しみにしています.

4

4 に答える 4

4

つまり、配列を割り当てるときは、連続したメモリが必要です。

100MB の巨大なブロックを 1 つ見つけるよりも、RAM 内にそれぞれ 10MB のサイズの連続したメモリの 10 ブロックを見つける可能性が高くなります。

アドレス 0 から 99 までの 100 バイトの RAM があるとします。たとえば、位置 23 にサイズ 1 バイトのメモリ ブロックを割り当てた場合、残りの RAM は 99 バイトですが、サイズが 99 バイトの場合、メモリは連続している必要があるため失敗します。このような場合に割り当てることができる最大のブロックは、76 バイトの長さになります。

于 2013-05-09T15:59:23.713 に答える
3

私には、それはメモリの断片化の問題のように見えます。newまた、ヒープを使用することに注意してください。

最初の例では、非常に大きなメモリのチャンクを要求しています。システムに搭載されている RAM の量に関係なく、OS がそれほど大きな連続したメモリ ブロックを見つけられない可能性があります。

メモリの連続した小さなブロックは、大きなブロックよりも常に十分にあるため、小さな割り当てが機能します。

于 2013-05-09T15:59:10.663 に答える