c# - 什么时候可以捕获 OutOfMemoryException 以及如何处理它?

标签 c# .net

昨天我参加了关于 OutOfMemoryException 及其处理优缺点的 SO 讨论 (C# try {} catch {})。

我处理它的优点是:

  • 抛出 OutOfMemoryException 的事实通常并不意味着程序的状态已损坏;
  • 根据文档“以下 Microsoft 中间 (MSIL) 指令抛出 OutOfMemoryException:box、newarr、newobj”,这只是(通常)意味着 CLR 试图找到给定大小的内存块,但无法做到这一点;它意味着我们没有留下任何字节;

但并非所有人都同意这一点,并推测此异常后程序状态未知,并且无法执行有用的操作,因为它需要更多内存。

因此我的问题是:不处理 OutOfMemoryException 并在发生时立即放弃的严重原因是什么?

已编辑:您认为 OOME 和 ExecutionEngineException 一样致命吗?

最佳答案

IMO,因为您无法预测在 OOM 之后您可以/不能做什么(因此您无法可靠地处理错误),或者其他 当将堆栈展开到您所在的位置时发生/没有发生(因此 BCL 没有可靠地处理错误),您的应用现在必须假定处于损坏状态。如果您通过处理此异常来“修复”您的代码,那么您就是在把头埋在沙子里。

我在这里可能是错的,但对我来说这条消息说大麻烦。正确的解决方法是弄清楚为什么你会吞噬内存,并解决这个问题(例如,你有泄漏吗?你能切换到流式 API 吗?)。即使切换到 x64 也不是 Elixir ;数组(以及列表)仍然有大小限制;并且增加的引用大小意味着您可以在 2GB 对象上限中修复数量较少的引用。

如果您需要机会处理一些数据,并且很高兴它失败:启动第二个进程(AppDomain 不够好)。如果它爆炸了,请拆除该过程。问题已解决,您的原始进程/AppDomain 是安全的。

关于c# - 什么时候可以捕获 OutOfMemoryException 以及如何处理它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2117142/

相关文章:

c# - 使用 C# 中的 Open Xml SDK 将 DataTable 导出到 Excel

c# - 只使用 UriKind.RelativeOrAbsolute 的坏习惯?

c# - 如何在 Razor View 中显示其他模型列?

c# - 我如何创建一个项目集合

c# - JQuery 和不可见的选择 - JQuery

.net - 如何更改网络图表上的图例符号?

c# - 如何从C#中的存储过程中获取所需的参数

c# - DB2Connection 对象循环打开然后关闭内存异常

c# - 如何流式传输(加载)XML 文件、修改 XML 元素数据以及写入 MemoryStream

c# - 在 Linux 上运行 Dot Net 项目 exe,它利用 System.Management 获取 USB 设备信息