昨天我参加了关于 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/