C编程中的内存处理策略是什么?

时间:2010-08-13 14:12:17

标签: c memory malloc

我自己的一个策略是在程序启动时分配5兆字节的内存(或者你认为必要的任何数字)。

然后,当程序的malloc()返回NULL时,您可以释放5兆字节并再次调用malloc(),这将成功并让程序继续运行。

您对此策略有何看法?

你知道其他什么策略?

谢谢,Boda Cydo。

9 个答案:

答案 0 :(得分:13)

优雅地退出处理malloc失败。使用现代操作系统,页面文件等,您永远不应先发制人地支持内存故障,只需优雅退出即可。除非您遇到算法问题,否则您不太可能遇到内存不足错误。

另外,在启动时无缘无故地分配5MB是疯狂的。

答案 1 :(得分:5)

在过去几年中,我一直使用的(嵌入式)软件通常不允许使用malloc()。唯一的例外是它在初始化阶段是允许的,但是一旦确定不允许更多的内存分配,所有将来对malloc()的调用都会失败。由于malloc()/ free()导致内存可能变得碎片化,在很多情况下,最好很难证明以后对malloc()的调用不会失败。

这种情况可能不适用于您的情况。但是,知道malloc()失败的原因可能很有用。我们在代码中使用的以下技术,因为malloc()通常不可用,可能(或可能不)适用于您的场景。

我们倾向于依赖内存池。每个池的内存在瞬态启动阶段分配。一旦我们拥有了这些池,我们就会在需要时从池中获取一个条目,并在完成后将其释放回池中。每个池都是可配置的,通常保留用于特定的对象类型。我们可以跟踪每个时间段的使用情况。如果我们用完了池条目,我们可以找出原因。如果我们不这样做,我们可以选择缩小我们的游泳池并节省一些资源。

希望这有帮助。

答案 2 :(得分:2)

作为一种测试方法,您可以优雅地处理内存不足的情况,这可能是一种非常有用的技术。

在任何其他情况下,充其量听起来毫无用处。你导致内存不足的情况发生,然后通过释放你不需要开始的内存来解决问题。

答案 3 :(得分:2)

“尝试-再次-后面”。仅仅因为你现在是OOM,并不意味着你会在系统不那么忙的时候出现。

void *smalloc(size_t size) {
   for(int i = 0; i < 100; i++) {
      void *p = malloc(size);
      if(p) 
        return p;
      sleep(1);
    }
   return NULL;
}

你当然应该考虑很多关于你采用这种策略的地方,因为它非常隐蔽,但它在各种情况下保存了我们的一些系统

答案 4 :(得分:1)

它实际上取决于您要实现的策略,这意味着程序在内存不足时的预期行为是什么。

很好的解决方案是仅在初始化期间分配内存,而在运行时期间永远不分配。在这种情况下,如果程序设法启动,你永远不会耗尽内存。

当你达到内存限制时,另一个可能是释放资源。实施和测试很困难。

请记住,当您从NULL获得malloc时,这意味着物理和虚拟内存都没有更多的可用空间,这意味着您的程序一直在交换,使其变慢并且计算机不响应。

您实际上需要确保(通过估计计算或通过检查运行时的内存量)计算机具有的预期可用内存量足以满足您的程序。

答案 5 :(得分:1)

通常,释放内存的目的是让您在终止程序之前报告错误。

如果你要继续跑步,那么预先安排应急储备是没有意义的。

答案 6 :(得分:1)

是的,这在实践中不起作用。首先,出于技术原因,典型的低碎片堆实现不会使大型空闲块可用于小分配。

但真正的问题是你不知道为什么你用完了虚拟内存空间。如果你不知道为什么那么你就无法阻止额外的内存被快速消耗而仍然使你的程序崩溃了。这很可能发生,你已经消耗了接近2千兆字节,额外的5 MB是热板上的一滴水。

任何将应用程序切换为“紧急模式”的方案都是非常不切实际的。您必须中止运行代码,以便停止,比如加载大量数据文件。这需要例外。现在你回到你之前已经拥有的东西,std :: badalloc。

答案 7 :(得分:0)

默认配置中的大多数现代操作系统都允许内存过量使用,因此您的程序根本不会从malloc()获取NULL,或者至少在某种程度上(错误地,我猜)用尽所有可用的地址空间(不是内存) 。 然后它写了一些完全合法的内存位置,得到页面错误,后备存储中没有内存页面和BANG(SIGBUS) - 你死了,没有好办法。

所以忘记它,你无法处理它。

答案 8 :(得分:0)

我想说明5mb预分配方法是“疯狂”的情绪,但另一个原因是:它受竞争条件的影响。如果内存耗尽的原因在您的程序中(虚拟地址空间耗尽),另一个线程可以在您释放之后但在使用它之前声明5mb。如果内存耗尽的原因是由于其他进程使用了​​太多内存而导致机器上缺少物理资源,那么其他进程可以在释放后声明5mb(如果malloc实现将空间返回给系统)。

某些应用程序,如音乐或电影播放器​​,在退出/崩溃分配失败时是完全合理的 - 它们管理很少(如果有的话)可修改的数据。另一方面,我相信任何用于修改具有潜在价值的数据的应用程序都需要有一种方法(1)确保磁盘上的数据保持一致,未损坏的状态,并且(2)写入删除某种类型的恢复日志,以便在后续调用时,用户可以恢复在强制关闭应用程序时丢失的任何数据。

正如我们在第一段中看到的,由于竞争条件,你的“malloc 5mb and free it”方法不起作用。理想情况下,同步数据和写入恢复信息的代码将完全无分配;如果你的程序设计得很好,它可能很自然地免费分配。如果您知道在此阶段需要分配,一种可能的方法是实现自己的分配器,该分配器在小型静态缓冲区/池中工作,并在分配失败关闭期间使用它。

相关问题