OutofMemory
例外の考えられる理由は何ですか。メモリ割り当ては GC で処理する必要があります。
通常の .NET/C# アプリケーションに割り当てられている/使用可能なメモリの量
私たちのアプリケーションでは、Stream.ReadToEnd()
やDataTable.WriteXml(Memory stream)
関数などのさまざまな場所にあります。
環境は.Net C#
OutofMemory
例外の考えられる理由は何ですか。
メモリ割り当ては GC で処理する必要があります。
通常の .NET/C# アプリケーションに割り当てられている/使用可能なメモリの量
私たちのアプリケーションでは、Stream.ReadToEnd()
やDataTable.WriteXml(Memory stream)
関数などのさまざまな場所にあります。
環境は.Net C#
OutOfMemory 例外は、次のいずれかの MSIL 命令の呼び出しが失敗するたびに発生します。
基本的に、ヒープに新しいメモリを割り当てる操作は、Stream.ReadToEnd が内部的にバイト配列を割り当ててストリームをメモリにロードするように見えるため、ファイルがプロセスを中断するのに十分な大きさの場合、この例外がスローされます。
アプリケーションが使用可能なメモリを使い果たしたか、ヒープの断片化に問題があります。
最初のケースでは、すべてのメモリを占有するのに十分なオブジェクトを作成しましたが、それらへの参照がまだ残っているため、ガベージ コレクターはそれらをクリーンアップできません。
2 番目のケースであるヒープの断片化では、ヒープ内の連続する最大のメモリ チャンクよりも大きなオブジェクトを作成しようとしています。これはよりまれですが、場合によっては確かに発生します。通常のヒープは gc の実行中に圧縮されますが、大きなオブジェクト ヒープは圧縮されません。
大きなオブジェクト ヒープに関する MSDNの優れた記事があります。
編集:メモリから抜け出す別の方法を思い出しました。サイズが 2GB を超えるオブジェクトの作成を試みることができます。これは、64 ビットでも .NET の最大オブジェクト サイズです。
アプリが利用できるよりも多くのメモリを使用しています。この場合、メモリの使用をより効率的にする方法を考える必要があります。ファイル/データベースを使用して、すぐに使用しないデータを保存する必要がある場合があります..
または、メモリ リークがあります。その場合、使用しなくなったメモリへの参照を削除して、GC がメモリを解放できるようにする必要があります。
C# または .Net を使用している場合は、CLR プロファイラーを使用してメモリを分析し、メモリがどのように使用されているかを確認できます。CLR プロファイラー
アプリで使用するメモリが最大 10MB あるとします。新しい List を作成し、それに Object インスタンスを追加します。ここで、各オブジェクト インスタンスの「重み」が 1MB であるとしましょう。したがって、最初の 10 個のインスタンスは問題なく追加されますが、最初の 10 個のインスタンスが割り当てられたすべてのメモリ (10MB) を使用した後、11 番目のインスタンスは OutOfMemoryException をスローします。
ガベージ コレクタは、「ガベージ」、つまり使用されないインスタンスを探します - 他のインスタンスがそれらを指していないため、使用できません。たとえば、インスタンスを含む List 型のインスタンス メンバーがある場合、GC は List もそのインスタンスも収集しません。リストにインスタンスを追加し続けると、OutOfMEmory 例外が発生する可能性があります。
アプリで使用するメモリを増やす必要がある場合は、次の vm 引数を使用します: Java youAppName -Xms128m -Xmx512m