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

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

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

您对此策略有何看法?

你还知道其他什么策略?

谢谢,Boda Cydo。

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

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

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

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

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

希望这可以帮助。

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

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

“稍后再试”。 仅仅因为你现在是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; } 

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

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

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

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

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

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

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

如果您要继续运行,那么预先分配应急储备是没有意义的。

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

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

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

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

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

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

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

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