首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >实际OOM和2GB对象OOM之间的区别?

实际OOM和2GB对象OOM之间的区别?
EN

Stack Overflow用户
提问于 2021-03-05 13:33:04
回答 1查看 118关注 0票数 1

我想知道为实际OOM抛出的OOM异常(内存耗尽)和当达到2GB对象限制抛出的异常是否有什么区别。

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

代码语言:javascript
复制
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执行了代码,并得到了以下异常:

  • 2GB对象限制
代码语言:javascript
复制
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
代码语言:javascript
复制
System.OutOfMemoryException
  HResult=0x8007000E
  Message=Exception of type 'System.OutOfMemoryException' was thrown.
  Source=ConsoleApp1
  StackTrace:
   at ConsoleApp1.Program.Main(String[] args)

从这里看,这两个异常(除了堆栈跟踪/源之外)似乎没有明显的区别。

另一方面,我从LINQPad中执行了完全相同的操作,得到了以下内容:

  • 2GB限制

  • 实际OOM

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

我的问题是检测/区分这两种情况,尽管我也很好奇为什么LINQPad和VS执行之间的错误信息不同。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-03-05 14:04:08

我可以解释LinqPad和Visual之间的区别:

如果运行x86 DEBUGRELEASE .Net Framework4.8,则生成以下代码:

代码语言:javascript
复制
static void Main()
{
    try
    {
        List<Data> a = new List<Data>(134217725);
    }
    
    catch (Exception e)
    {
        Console.WriteLine(e.Message);
    }

    try
    {
        List<Data[]> b = new List<Data[]>();

        for (int i = 0; i < 13421772; i++)
        {
            b.Add(new Data[134217724]);
        }
    }

    catch (Exception e)
    {
        Console.WriteLine(e.Message);
    }
}

对于RELEASE构建,您可以得到:

代码语言:javascript
复制
Array dimensions exceeded supported range.
Exception of type 'System.OutOfMemoryException' was thrown.

对于DEBUG构建,您可以得到:

代码语言:javascript
复制
Exception of type 'System.OutOfMemoryException' was thrown.
Exception of type 'System.OutOfMemoryException' was thrown.

这意味着LINQPAD版本为RELEASE,Visual版本为DEBUG

所以答案是:是的,很明显有一些不同,但是:

  • 只有消息不同
  • 我们不应该依赖这种永不改变的状态。
  • 它在DEBUGRELEASE构建之间有所不同。

撇开:

在我的PC上,上面测试代码的DEBUG构建立即抛出两个OutOfMemoryException异常。

然而,RELEASE构建会很快抛出第一个OutOfMemoryException,但在抛出第二个异常之前还需要几秒钟。在此期间,它的内存使用量增加(根据任务管理器)。

因此很明显,至少对于.Net Framework4.8,遮罩下还有其他一些不同之处。我还没有在.Net 5或.Net Core中尝试过这一点。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66493512

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档