【问题标题】:What are best practices for dealing with out of memory errors?处理内存不足错误的最佳做法是什么?
【发布时间】:2010-12-21 02:05:55
【问题描述】:

我想知道,处理内存不足错误有哪些好的做法。

void SomeTask()
{
   try
   {
      SomeObj obj = new SomeObj();
   }
   catch( std::bad_alloc& )
   {
      // What should be done here?
   }


   // ... more code ...
}

我觉得静默返回是错误的,因为程序可能在不确定的状态下运行。那么,这里应该发生什么,我应该让程序崩溃,还是有更好的选择?该程序作为服务运行,所以我不能只弹出错误消息。我想如果有足够的内存来做这件事,可能会记录一些东西。但是,我只是想知道,在这种情况下,您认为我应该怎么做?

谢谢。

【问题讨论】:

  • 首先,不要测试null。抓住std::bad_alloc
  • 其次,除非你能修复它,否则不要捕获 bad_alloc。这很少靠近分配点。如果这是由主事件循环启动的某种服务,则允许服务退出并一直回到事件循环。如果这是正常应用程序流程的一部分,那么通常的结果就是让抛出导致应用程序终止。在 main() 中捕获并记录所有异常,然后重新抛出异常。

标签: c++ memory


【解决方案1】:

因为它是一项服务,所以我会在系统消息日志中写入一个错误。在 Windows 中,您可以使用 Windows Event Log API。除非您在文档中另有说明,否则这可能是系统管理员希望看到失败报告的地方。

此外,在大多数 C++ 编译器中,std::bad_alloc() 已经取代了堆分配失败的空返回值。

-保罗赫

【讨论】:

  • 如果您收到std::bad_alloc,那么失败的可能性也不小。
【解决方案2】:

由于它作为服务运行,因此最好让它崩溃,但首先通过记录错误状态然后中止或自行终止以一种可控的方式让它崩溃。服务控制管理器可以配置为在服务停止不受控制时重新启动服务。

如果可能的话,您可以通过强制对自身进行受控转储来走得更远,这样就可以找到问题的原因。

你的直觉是让它死掉,因为还有什么过程要做?一旦它到达内存不足状态,它就永远不会恢复到健康状态。 RIP 进程。

【讨论】:

  • "never" 可能有点太强了。在某些情况下,您可以从 OOM 状态中恢复。但在一般情况下,你是对的,除了让它终止之外,你无能为力。
  • 你说得对,我可以用“它很可能不会”恢复健康状态。然而,在终止之前倾倒的好处是巨大的。
【解决方案3】:

您应该做的第一件事是尝试释放更多内存。如果您必须定期擦洗对象,现在是时候这样做了。如果一切顺利,你也许还能继续跑步。

否则,您应该尝试将需要保存的任何内容保存到磁盘并死掉,如果您需要额外的内存,请确保在启动时预先获取它。由于继续运行是不可能的,你应该死掉(abort 或重新抛出异常)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-10
    • 1970-01-01
    • 1970-01-01
    • 2010-09-22
    • 2015-06-12
    • 2017-11-13
    • 2017-12-26
    • 1970-01-01
    相关资源
    最近更新 更多