C++では、ヒープにメモリを割り当てずに値で例外をスローすることが実際に可能であるため、この状況は理にかなっています。しかし、.NETフレームワークでは、OutOfMemoryException
は参照型であるため、ヒープに割り当てられます。新しいオブジェクトを作成するのに十分なメモリがない場合、.NET FrameworkはどのようにしてOutOfMemoryException
にメモリを割り当てますか?
ランタイムによって事前に割り当てられます。管理対象プロセスのヒープを調べると、その例外のインスタンスが見つかります。
Hello Worldアプリの事前に割り当てられた例外は次のとおりです。
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
ランタイム内でメモリ不足状態が発生すると、 ThrowOutOfMemory を呼び出します。これは、 Exception :: GetOOMException を呼び出します。これは、スタック上にオブジェクトを構築し、静的に割り当てられたグローバルインスタンスにコピーしてからスローします。
これはマネージ例外ではありませんが、 ex.h で宣言されたC++例外です。 C++例外は、事前に割り当てられたmanagedOutOfMemoryExceptionを具体的にスローするコードを含む clrex.cpp でマネージ例外に変換されます appdomain.cpp で最初に割り当てられ、構築されました。
注:これらのソースファイルの一部はサイズが大きく、構文の強調表示を読み込むときにブラウザが数秒間ハングすることがあります。
Tim Schmelterが他の回答のコメントでリンクした呼び出しサイトは、メモリ不足でオブジェクトを構築できないランタイムとは関係ありません。