2011-01-29 12 views
1

私はちょうど私が例外「System.OutOfMemoryExceptionに」がスローされた取得しています私のWindowsアプリケーションプロジェクトの2行目(results1)上でOutOfMemoryExceptionエラー

double[] results = new double[100000000]; 

double[] results1 = new double[100000000]; 

を2行を書いメートル。うまく

は私のシステム構成である

RAM-4ギガバイト

OSである - Windows 7の

プロセッサ - どのように私はこのエラーを解決し、なぜでき2.93 GHzの

をデュオインテルコアこのエラーが発生しました

ok答えのほとんどは総称リスト

に翻訳されています10
 List<int> results1 = new List<int>(); 
     List<int> results2 = new List<int>(); 



     for (int i = 0; i <= 100000000; i++) 
     { 
      results1.Add(i); 
      results2.Add(i); 
     } 

私はあなたがメモリに収まることができないので、大きな配列を割り当てるべきではありませんまた、ここで

+1

[OutOfMemoryExceptionの大規模配列の宣言]可能な複製(http://stackoverflow.com/questions/4815461/outofmemoryexception-on-declaration-of-large-array) – ChrisF

+0

なぜあなたはそのような**巨大な**が必要ですか?アレイ?あなたは何倍のダブルスを必要としますか? – BoltClock

+0

この質問は配列についてではない、私は希望のエラー –

答えて

5

を同じエラーを取得しています。単にリストを使用し、必要に応じて要素を追加:documentationから

var results = new List<double>(); 

引用:

int[] array = new int[5]; 

この配列は 配列から要素を含む[0]アレイ[4]。新しい演算子 は配列の作成に使用され、 は配列要素を デフォルト値に初期化します。この例では、すべての 配列要素が ゼロ

に初期化されているので、あなたはそれらのデフォルト値を保持するのに十分なメモリを持っている必要があります。

+0

よく私は交換コードについては、そのエラーの理由について –

+0

しかし、それはあなたのエラーを解決する? – Skurmedel

+1

@slash shogdhe、エラーの理由は、 'new'演算子を使うとメモリが割り当てられ、すべての要素がデフォルト値に割り当てられ、100000000 x 8バイト= 762MB doubleを割り当てることができないからです。あなたがこれを呼んでいる瞬間に利用可能です。 –

8

アレイを作成するとき、メモリアロケータは、割り当てたポイントで必要なメモリの総量を予約しようとします。この場合、各要素の8バイトになります。この場合のOOMはかなり簡単です。そのような大きな配列を割り当てるには十分なメモリがありません。スタンドアローンの32ビットWindows構成では、ユーザーコードとデータのプロセスあたり最大2GBのメモリアドレススペースに制限されていますが、実際には、メモリの断片化などにより、これよりはるかに少ないことがあります。断片化の場合、OOMは、大きな配列を扱うときには、「十分に大きな連続したメモリセクションを見つけることができない」と解釈する方が適切です。

5

これは、win32プロセススペース(2GB)にロードしようとしている800MBのアレイです。連続的である必要もあり、それによってさらに難しくなります。単純に - は、LOHの大きなブロックであるを見つけることができません。

の3つのオプション:

  • は、このような巨大な配列を割り当てません - あなた本当にはそれを必要ですか?
  • ギザギザの配列に切り替えます。複数の中間サイズの配列を割り当てる方が簡単です。例えばdouble[][] 10000有する内側列長10000の各 - ちょうどのx64に右ブロックに
  • スイッチを得るために、いくつかの/%コードを実行し(配列は依然として2ギガバイトにハード制限であることに注意)
+2

@slash - double = 8バイト、100000000セルを掛けたもの。 KBは1024で、MBは1024でもう一度割ります。 –

+0

Jaggedアレイはどのように問題を解決していますか?あなたはまだ同じ量のメモリが必要だと思います。何か不足していますか? – Sandeep

+0

@Sandeepは*連続である必要はないからです。フラグメント化された大きなオブジェクトヒープでは、十分な*中規模のブロックを見つけることができるかもしれませんが、1つの大きな巨獣を見つけることは苦痛です。また、必要に応じて、上部ブロックの割り当てを遅らせることができます。 –

2

私は間違っているかもしれませんが、配列を割り振るときは通常、少なくとも多くの言語で意味します。つまり、の連続したメモリブロックを要求しています。 100,000,000要素の倍数の単一配列は、100000000 * 8バイトのメモリ(+オーバーヘッド)、約800メガバイトを必要とします。空き容量(合計)が空き容量であるとは限りませんが、必ずしも空きメモリが連続しているとは限りません。サイズが異なる複数の空き領域に分割され、割り当てが失敗します。

2

考えられる理由の1つは、仮想アドレス空間の断片化です。メモリマネージャは、最初の800MBの連続したアドレス空間チャンクを見つけることができます。しかし、それは2番目を見つけることができませんでした。

0

エラーの理由は、アレイが、あなたがコードを実行するとき、それはあなたのシステム上のすべての空きRAMを占めるほど大きいことです。ダリンが言ったことは正しいです。それは大きな配列を作るのは意味がありません。ほとんどのシステムでは、繰り返し処理するのが永遠に進み、あまりにも多くのRAMが必要になります。

+3

OOMは空きRAMではありません**。コンピュータは仮想メモリと動的マッピングを広範囲に使用しているため、**は全くありません。それを仮想アドレス空間にマッピングすることです。 http://blogs.msdn.com/b/ericlippert/archive/2009/06/08/out-of-memory-does-not-refer-to-physical-memory.aspx –

1

私の知る限りでは、リストは以下のように動作します。リストの長さが2^n個の上に成長している場合は、別の2^n個の要素が割り当てられています。したがって、リストの長さは67108864(= 2^26)で、別の2^26要素を割り当てます。それはまさに私があなたのコードを実行している場合、エラーが発生するポイントです。 intの代わりに長い変数を使用すると、33554432の長さのエラーが発生します。正確には2^25です。どちらも意味があります。

したがって、intは4バイトを取るので、最初のリストは2^27 * 4バイトのメモリスペースを既に割り当てられているので、2^26より長くなります。したがって、2^29バイトです。 2番目のリストにさらにスペースを割り当てようとすると、メモリーは2^30バイトを超えて1GBになります。

私はそこgenerellのRAMの制限があり、それは程度連続した空きアドレス空間、また、あなたのプロセスのために約1 GBのRAMの制限だけではないと考える理由です。この限界がどこから来るのかは分かりません。

32ビットマシン上で同様の問題に関するいくつかのポストhereがあります - 私はあなたの勝利7は32ビットまたは64ビットであるかどうかわかりません。 EDIT:アプリケーションを64ビットモードで実行しましたが、問題はなくなりました。だから私はちょうど上記の投稿を参照することができます。また、プロジェクトのプロパティのプラットフォームを64ビットに変更する必要があります。

1つの質問だけが残っています。なぜこのような大きなリストを持ちたいのですか?これは実際にはメモリを消費し、そのような割り当てを避ける方法はたくさんあります。

希望に役立ちます。