【问题标题】:How can I debug OutOfMemoryException without stacktrace?如何在没有堆栈跟踪的情况下调试 OutOfMemoryException?
【发布时间】:2019-10-23 06:50:05
【问题描述】:

当我在 linux 服务器上运行我的 .NET Core 应用程序时,我得到了 OutOfMemoryException。我完全不知道如何调试它,因为没有提供堆栈跟踪。唯一的输出是:“未处理的异常:OutOfMemoryException。”

在抛出这个异常的那一刻,还有足够的空间。使用了 200 GB 的 RAM,300 GB 是免费的,所以我认为内存应该没有任何问题。

它发生的那一刻是我尝试将一个对象序列化为 protobuf。最终文件应约为 1GB。我以前从未遇到过这个问题,并且模型序列化得很好。

我将非常感谢任何见解。我真的需要让它工作:(我已经尝试在序列化之前调用它,因为我认为问题出在碎片上。经过 10 个小时的计算,我意识到事实并非如此。

_logger.LogDebug("LOH compaction start");
GCSettings.LargeObjectHeapCompactionMode = 
GCLargeObjectHeapCompactionMode.CompactOnce;
GC.Collect();
_logger.LogDebug("LOH compaction end");

抛出异常时我正在执行的代码是这样的:

        public static void Serialize<T>(this ProtobufSerializer protobufSerializer, string filePath, T serializationObject)
        {
            using (var fileStream = new FileStream(filePath, FileMode.Create))
            {
                protobufSerializer.Serialize(fileStream, serializationObject);
            }
        }

【问题讨论】:

  • 可怕的数字。它绝不是由按需页面虚拟内存操作系统上没有足够的 RAM 引起的。在 Linux 上,您首先要确保系统交换空间足够大。
  • 您能否编辑您的帖子以包含异常发生时正在执行的代码? (顺便说一句,你到底在序列化这么大的东西?)
  • @JohnWu 我编辑了我的帖子。这些是用于预测功能销售的模型。有关于公司中每家商店和产品的信息,以及我们应该使用哪种模型进行这种组合以获得最佳预测
  • @HansPassant 我从没想过交换大小。它是 30GB。 500GB RAM可以吗?
  • 这太低了,毫无意义。与配置机器的人交谈,他们可能会选择这么低的数字,认为半 TB 的 RAM 总是足够的。直到它不是。

标签: c# out-of-memory


【解决方案1】:

您需要一种非常系统的方法来识别和解决 OOM。

  1. 不要认为如果您有大量可用 RAM,则全部用于您的应用程序。
  2. OOM 是非常臭名昭著的伪装自己,您可能会看到堆栈跟踪指向其他地方,而问题实际上可能出在其他地方,从某种意义上说,其他一些代码正在泄漏/消耗大量内存,并且已将内存使用置于边缘并且在其他地方试图保护一些有限内存的合法代码会将其推送到 OOM。
  3. 使用一些分析器并确定内存增加/泄漏的区域。 (看起来您已将此识别为序列化大数据的代码。)
  4. 然后处理这些区域并尽量减少内存使用量。

【讨论】:

  • 我使用 Google.Protobuf,它看起来无法序列化这些数据,尽管它过去序列化了更大的数据。是否可以了解该 protobuf 的 Serialize 方法是否在内部分配?
【解决方案2】:

只有当您的系统位大小未达到您使用的对象的大小级别时,才会引发 OutOfMemory 异常。

OutOfMemoryException 异常有两个主要原因:-

1.您正在尝试将 StringBuilder 对象扩展至超出其 StringBuilder.MaxCapacity 属性定义的长度。

2.公共语言运行时无法分配足够的连续内存来成功执行操作

【讨论】:

  • (1) 和 (2) 都不是这样。我不使用 StringBuilder 并且有 300GB 的可用 RAM。在抛出 OutOfMemoryException 的那一刻,即使是 RAM 使用量也远高于 200GB。
猜你喜欢
  • 2013-12-31
  • 2010-11-07
  • 2013-08-03
  • 2011-02-05
  • 1970-01-01
  • 2018-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多