性能问答>实际 OOM 和 2GB 对象 OOM 之间的区别是什么?>
1回复

实际 OOM 和 2GB 对象 OOM 之间的区别是什么?



想知道为实际 OOM(内存耗尽)抛出的 OOM 异常与达到2GB 对象限制时抛出的异常之间是否存在一些差异?

以下是导致 OOM 的代码(没有 app.config 更改,gcAllowVeryLargeObjects默认设置为false):

struct Data
{
    double a;
    double b;
}

// Causes OOM due to the 2GB object limit.
List<Data> a = new List<Data>(134217725);

// Causes OOM due to actual OOM.
List<Data[]> b = new List<Data[]>();
for (int i = 0; i < 13421772; i++)
{
    b.Add(new Data[134217724]);
}

从 Visual Studio 执行代码后,出现以下异常:

  • 2GB 对象限制
System.OutOfMemoryException
  HResult=0x8007000E
  Message=Exception of type 'System.OutOfMemoryException' was thrown.
  Source=mscorlib
  StackTrace:
   at System.Collections.Generic.List`1..ctor(Int32 capacity) 
   at ConsoleApp1.Program.Main(String[] args)
  • 实际的OOM
System.OutOfMemoryException
  HResult=0x8007000E
  Message=Exception of type 'System.OutOfMemoryException' was thrown.
  Source=ConsoleApp1
  StackTrace:
   at ConsoleApp1.Program.Main(String[] args)

从这里开始,这两个异常之间似乎没有显着差异(堆栈跟踪/源除外)。

另一方面,从 LINQPad 执行完全相同的操作并得到以下结果:

  • 2GB 限制

LINQPad 2GB 限制异常

  • 实际OOM

LINQPad实际OOM异常

RuntimeInformation.FrameworkDescription从两个地方执行都会导致.NET Framework 4.8.4341.0

关于这两种情况,好奇为什么 LINQPad 和 VS 执行之间的错误消息提示会不一样?

133 阅读
请先登录,查看1条精彩评论吧
快去登录吧,你将获得
  • 浏览更多精彩评论
  • 和开发者讨论交流,共同进步