处理"内存不足"的正确方法是什么?

abl*_*lmf 7 c malloc

最近,我在Windows上制作了一个CCTV节目的视频播放器程序.由于程序必须同时解码和播放许多视频流,我认为它可能会遇到malloc失败的情况,我在每个malloc之后添加检查.

但从口头上讲,在我在开源项目中阅读的这些开源程序代码中,我很少发现对malloc结果的任何检查.所以当malloc失败时,大多数程序都会崩溃.那不是不接受吗?

我在linux上编写服务器程序的同事会为100个客户端连接分配足够的内存.因此,虽然他的程序可能会拒绝101客户端,但它永远不会遇到malloc的失败.他的方法是否也适用于桌面应用程序?

Joh*_*kin 12

在Linux上,malloc()永远不会失败 - 相反,OOM杀手将被触发并开始杀死随机进程,直到系统崩溃.由于Linux是当今最流行的UNIX衍生产品,许多开发人员已经学会了从不检查结果malloc().这可能是你的同事忽视malloc()失败的原因.

在支持失败的操作系统上,我看到了两种常规模式:

  • 编写一个自定义过程来检查结果malloc(),并abort()在分配失败时调用.例如,GLib和GTK +库使用这种方法.

  • 存储"可清除"分配的全局列表,例如缓存,可在分配失败时清除.然后,再次尝试分配,如果仍然失败,则通过标准错误报告机制(不执行动态分配)报告.

  • 很容易激发`malloc`在Linux系统上返回NULL - 只需在运行程序之前用`ulimit`设置进程内存限制.如果要测试程序如何处理内存不足的情况,这非常有用. (6认同)
  • 不检查malloc的返回值的做法比Linux已经存在的时间要长得多.这与不检查printf的返回值的心态有关 - 它们中的任何一个失败的可能性有多大?但malloc的手册页将OOM行为列为"bug",并描述了一种禁用它的方法,因此malloc在发生故障时返回NULL. (5认同)
  • 当你说它不能失败时,你的意思是它不会以程序可以管理或控制的方式优雅地失败.请参阅此讨论http://ubuntuforums.org/archive/index.php/t-1214975.html (4认同)
  • @Barry:我不检查`printf()`的返回值,不是因为我认为它是绝对可靠的,而是因为我不关心它是否失败. (3认同)
  • @Clifford:如果输出的字符数小于我期望它写的数字,那么它就失败了. (3认同)
  • -1 第一句话是完全错误的。正确的说法是“在 Linux 的默认配置中,`malloc` 有时会在内存不可用的情况下成功,从而导致调用程序或另一个程序在稍后不可预知的时间被内核 OOM 杀手杀死。 ” 即使启用了过量使用,`malloc` 仍然很容易失败,例如当你耗尽虚拟地址空间时。 (2认同)

Dig*_*oss 6

遵循标准化API

即使在Linux上,ulimit也可用于获取malloc错误返回的提示.它只是默认为无限制.

符合公布标准的压力很大.在大多数系统上,从长远来看,最终甚至在Linux上,malloc(3)都会返回正确的失败指示.桌面系统确实具有虚拟内存和请求分页,但即使这样,检查也malloc(3)只能在没有内存泄漏的调试程序中运行.如果出现任何问题,有人会想要设置ulimit并跟踪它.突然间,malloc检查是有道理的.