在C ++中,实际上可以通过值抛出异常而无需在堆上分配内存,因此这种情况很有意义。但是在.NET框架中OutOfMemoryException
是引用类型,因此它在堆上分配。
当没有足够的内存来创建新对象时,.NET框架如何为OutOfMemoryException
分配内存?
答案 0 :(得分:162)
它由运行时预先分配。如果您浏览任何托管进程的堆,您将找到该异常的实例。
以下是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
答案 1 :(得分:41)
当在运行时内遇到内存不足的情况时,它会调用ThrowOutOfMemory。这将调用Exception::GetOOMException,它构造堆栈上的对象,然后将其复制到静态分配的全局实例,然后抛出该实例。
这不是托管的异常,但它是ex.h中声明的C ++异常。 C ++异常转换为clrex.cpp中的托管异常,其中包含专门抛出预先分配的托管 OutOfMemoryException的代码,该异常最初是在appdomain.cpp中分配和构建的。
注意:其中一些源文件较大,可能会在加载语法高亮显示时将浏览器挂起几秒钟。
Tim Schmelter在对另一个答案的评论中链接的调用站点与运行时内存不足和无法构造对象无关。