2015-10-30 3 views
139

C++では、実際には、ヒープ上にメモリを割り当てずに例外をスローすることができます。しかし.NET FrameworkではOutOfMemoryExceptionは参照型なので、ヒープに割り当てられます。 新しいオブジェクトを作成するのに十分なメモリがない場合、.NET FrameworkはOutOfMemoryExceptionのメモリをどのように割り当てますか?.NET FrameworkはOutOfMemoryExceptionのためにどのようにメモリを割り当てますか?

+5

優秀な質問です。たぶん、その状況のた​​めに十分なメモリが予約されている可能性があります。 – GreatAndPowerfulOz

+18

OOMは、リクエストしたブロックを割り当てることができないことを意味しています。あなたが100Mbを要求し、ランタイムが見つけることができる最大の利用可能なブロックが99Mbだけであれば、それは失敗します。しかし、OOM例外は数バイトのメモリしか必要としません。つまり、割り当てが失敗しただけで、メモリがゼロになったということではありません。しかし、もちろん、ランタイムはこの状況でそれ自身をカバーするためにいくらかのメモリを予約する可能性が高いです –

+3

C++に関するあなたの前提は間違っています。コンパイラによっては、例外がヒープに割り当てられる可能性があります。 MSコンパイラは、Common C++ ABIでは、ヒープに例外が割り当てられていますが、ヒープ上にスペースが残っていない場合には代わりに使用される小さな事前割り当てされた緊急バッファがあります。 –

答えて

155

ランタイムによって事前に割り当てられます。管理対象プロセスのヒープを調べると、その例外のインスタンスが見つかります。メモリ不足の状態がランタイムの内部で発生した

0:003> !dumpheap -stat -type Exception 
Statistics: 
     MT Count TotalSize Class Name 
735f2920  1   84 System.ExecutionEngineException 
735f28dc  1   84 System.StackOverflowException 
735f2898  1   84 System.OutOfMemoryException 
735f2744  1   84 System.Exception 
735f2964  2   168 System.Threading.ThreadAbortException 
+3

しかし、[OutOfMemoryException'のコンストラクタ(http://referencesource.microsoft.com/#mscorlib/system/outofmemoryexception.cs,5ad855b434264d4b,references)が呼び出されています。 –

+0

申し訳ありませんが、私はあなたのポイントが何であるか分かりません。 –

+35

ランタイムは、コードと同じルールで再生する必要はありません。別の例では、 'StackOverflowException'を投げるとcatchすることができますが、実行時にその例外がスローされた場合は、デフォルトでcatchできません。 –

39

が、それはThrowOutOfMemoryを呼び出します。ここでは

は、Hello Worldのアプリの事前に割り当てられた例外です。これは Exception::GetOOMExceptionを呼び出し、スタック上にオブジェクトを構築し、それを静的に割り当てられたグローバルインスタンスにコピーしてスローします。

これは、しかし、それはC++例外ex.hで宣言され、管理さ例外ではありません。 C++の例外は、具体的には事前に割り当てられが元々割り当てられappdomain.cpp構築したのOutOfMemoryExceptionを管理スローするコードを含む、clrex.cppで管理例外に変換されます。

注:これらのソースファイルの一部が大きく、それが構文の強調表示をロードしながら数秒間ブラウザをハングすることがあります。ティムSchmelterが他の回答にコメントでリンク

呼び出しサイトは、ランタイムがメモリ不足やオブジェクトを構築することができないことに関連していません。

関連する問題