我自己的一个策略是在程序启动时分配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”方法不起作用。 理想情况下,同步数据和写入恢复信息的代码将完全免分配; 如果你的程序设计得很好,它可能很自然地免费分配。 如果您知道在此阶段需要分配,一种可能的方法是实现自己的分配器,该分配器在小型静态缓冲区/池中工作,并在分配失败关闭期间使用它。
以上就是c/c++开发分享C编程中的内存处理策略是什么?相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/545027.html