您是否处理内存不足的情况?


Answers:


4

我会像避免崩溃一样避免OOM。

避免一次执行大量工作(并分配大量内存)。将数据保留在磁盘上,信任OS磁盘缓存,并尽可能多地使用内存映射的IO,并且一次只能处理一小部分数据。如果需要在线存储大量数据(以低延迟提供),则像所有大型搜索引擎公司一样,将它们保存在多台计算机的内存中。或购买SSD。


显然,这最有意义。
mbq 2010年

2
关于如何优雅地处理OOM(RAII,异常安全,等等),存在着很大的争论,但是一旦我意识到在具有多个动态模块(某些来自第三方)的多线程系统中,即使您的线程没有崩溃,有不幸的时候一个时刻,每一个线程会看到OOM。如果甚至只有一个人决定继续前进,那么除了目击者之外,您什么也做不了。
rwong

13

回答这个问题的大多数人可能从未在嵌入式系统上工作过,因为malloc返回0的可能性非常大。在我当前正在使用的系统上,总共有4.25K字节的RAM(即4352字节)。我为堆栈分配了64个字节,当前有1600个字节的堆。就在昨天,我正在调试堆遍历例程,以便可以跟踪内存的分配和释放。堆遍历使用一个小的(30字节)静态分配的缓冲区输出到串行端口。对于发行版本,它将关闭。

由于这是消费类产品,因此最好不要在产品发布后耗尽内存。我相信它将在开发过程中。无论如何,我所能做的就是让扬声器发出几次哔声,然后重新启动。


2
在很小的空间内安装功能真是令人惊讶...这是一种艺术形式,例如盆景
rwong

6
嵌入式系统上的许多项目只是禁止动态分配内存。OOM的唯一情况仍然是堆栈溢出。
mouviciel

您是对的,但尤其是第一句话:幸运的是,大多数情况与大多数开发人员无关。
康拉德·鲁道夫2012年

4

老实说,在我完成的所有项目中(请记住,我还没有在任何地方工作),我从来没有考虑过可能发生这种情况,因此我想我的程序会很快死掉。

此外,处理OOM要求您预先分配资源以显示错误消息或保存所有内容,这可能会带来不便。

我觉得这些天,内存的花费要比花生便宜,这不是应该经常发生的事情。在受保护的记忆之初以及之前,也许这是个问题,但是现在呢?我见过的唯一的OOM错误是来自错误代码。


我可以考虑回收该进程已经拥有的一些内存,并尝试生存和恢复(如果您转储了有用的东西,则为硬存储)或作为试图保存它的数据和剩余部分而生存。
mbq 2010年

2

无论如何,检查malloc返回代码通常是毫无意义的。

现代操作系统过量使用内存:它们为进程提供的内存超过了实际可用的内存。授予您的进程的内存是虚拟的,所有内存都映射到单个清零页面。

直到您写入内存后,才会为进程分配一个物理的唯一页面。如果此分配失败,内核将终止进程(也许是您的进程!)以尝试查找内存。到那时,您无能为力了。


我有一个想法,可以进入带有长时间睡眠的while循环-如果该过程可以幸免于难,可以恢复。我给人的印象是,由于试图使用0地址,进程被终止了,但是我没有做任何可靠的测试。
mbq 2010年

您无需采取任何特殊措施即可处理OOM杀手。如果您的进程触发了它但未被选中,它将永远不会知道。一切都会好像有足够的内存一样工作。另一方面,如果选择了您的过程,则该过程将终止,您也无能为力。
克里斯托弗·普罗沃斯特

但是我可以尝试等待OOM释放一些内存,然后尝试再次分配并继续。我的印象是,malloc / new没有等待这种情况的发生。
2010年

不,你不能。您的分配将始终成功。您将获得所需的所有虚拟内存。直到您触摸它,才分配物理内存。触摸未分配的页面后,过程将暂停。内核将寻找更多的内存,这可能导致内核杀死更多内存的进程。如果成功(并且不会杀死您!),将分配页面并且您的过程将恢复。您的过程无法告诉您已发生这种情况。
克里斯托夫·普罗沃斯特

2
我很确定Windows绝对不会过量使用。它可以提交的内容比RAM多,但不能超过RAM + swapfile。
CodesInChaos 2012年

2

除非您是为嵌入式系统,实时系统或如此关键的系统而开发,否则故障可能会导致生命或数十亿美元的损失。

在大多数情况下,无论如何,当您的内存不足时,几乎无能为力,因为没有内存可以创建任何新对象或执行任何可能做某事的任务。您必须权衡处理OOM的应用程序成本与从中获得的收益。


实时系统不需要比其他系统更多地检查malloc故障。
zneak 2010年

@zneak-不正确。实时系统必须是可预测的,而内存不足是不可预测的,除非您专门为此计划。
Erik Funkenbusch

那么一旦达到OOM,您还要做什么?
zneak

释放内存,取消进程等。实时系统通常没有虚拟内存或交换系统,因为它必须具有确定性。因此,它可以更容易地用完内存。
Erik Funkenbusch

给定一定的代码路径将不可避免地导致OOM错误,我不认为崩溃是比释放内存和取消进程少确定性的方法。
zneak 2010年

1

我将始终检查错误。如果某些内容返回错误情况,则必须由程序处理。即使该消息说“内存不足,该走了!”,它也比“访问冲突”,“核心已转储”或其他任何方法要好。一个是您处理的错误条件,另一个是错误。并且用户也将同样如此。

对于您的特定情况,您可以尝试回滚操作,释放分配的资源,直到达到故障点为止,报告错误,然后继续执行(也许在尝试退出应用程序时,您可以选择立即退出)。这样,用户可以决定该怎么做,或尝试通过摆弄,关闭文件等来释放一些内存。当然,如何处理这种情况在很大程度上取决于您的程序-该程序不应进行交互可能只需要记录错误并退出或继续即可。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.