- 没有特殊处理。让malloc()返回NULL,并让它被解引用以导致整个程序崩溃。
- 在malloc()失败时立即退出,通过调用abort()或exit(-1)。假设环境会清理所有东西。
- 跳出主事件循环并尝试pthread_join()所有线程,然后关闭。
那我该怎么办呢?
选项2没有问题。不必假设-exit()
退出进程,这意味着所有线程都被关闭并且所有内容都被清理。
不要忘记尝试记录分配失败的位置。
malloc()
失败时,尝试保存当前应用程序状态可能是不可能的 - 更好的策略是在一切正常运行时为应用程序创建定期检查点以保存到持久存储中。 - cafmalloc()
失败时,很难“治愈”这种失败。你有一些选择:
malloc()
(完全不使用或通常情况下不使用)。您可以包装malloc()以在失败时执行额外的工作,例如通知其他内容。当使用类似看门狗的东西时,这很有帮助。您还可以使用一个完整的垃圾收集器,但我不建议这样做。最好识别并修复泄漏。malloc()
,不会超卖它。如果您已经广泛地对堆使用进行了剖析(使用像Valgrind的massif或类似工具),则可以合理地调整池的大小。然而,大多数建议的实质都是不信任/不使用系统malloc()
,如果失败不是选项。
malloc()
失败时通知看门狗,以便可以重新启动您的进程(或整个系统)。您不希望它在死锁状态下仍然表现得“活着并运行”。这可能只需要取消链接文件即可。malloc()
失败,则表明您的进程无法继续可靠运行。如果尝试获取数百MB时失败,则您可能能够恢复并继续运行。因此,您采取的任何行动都应基于您要获取的内存量以及是否仍然成功分配较小大小的调用。还有第四种选择:释放一些内存(缓存通常是不错的选择),然后再尝试。
如果您负担不起这个代价,我会选择第二种选项(记录或打印某种错误消息,显然)...唯一需要考虑的清理问题是以有序的方式关闭打开的网络连接,以便客户端知道另一端的应用程序正在关闭,而不是发现意外的连接问题。
我认为这取决于你的架构。
malloc()
失败是否意味着只有该线程无法继续,还是在这种情况下整个进程都会崩溃?
通常情况下,当内存非常紧张(即微处理器环境)时,为避免出现此类问题,最好避免所有动态内存分配。
从个人经验来看,我可以说malloc失败的频率经常被高估了。例如,在Linux中,通常的“解决方案”是2的变体,你不会得到malloc失败的提示。进程只是突然死亡。在更大的系统上,一旦交换使其无响应,应用程序往往会因为用户或看门狗而死亡。
这使得清理工作有点困难,也使得想出一个通用解决方案变得困难。
这个程序在操作系统上运行吗?使用pthread表明如此。您知道甚至malloc()会返回NULL吗?在某些系统上(例如Linux),故障将在malloc()内部发生,并由操作系统处理(通过终止进程),而不是malloc()返回。
我建议您在应用程序初始化时分配一个内存池,并从该内存池中进行分配,而不是在初始化后使用malloc()。这将使您控制内存分配算法和内存耗尽时的行为。如果内存池不足,则在应用程序启动之前会有一个单点故障,无法完成任何操作。
在实时和嵌入式系统中,通常使用'固定块内存分配器'。如果您的操作系统没有提供服务,则可以通过预先分配内存块并将它们的指针放置在队列上来实现。要分配块,您需要从队列中取出指针,要释放它,您需要将其放回队列中。当队列为空时,内存已耗尽,您可以选择拒绝并处理错误,或者阻塞并等待另一个线程返回一些内存。您可能希望创建具有不同大小块的多个池,甚至为特定目的创建一个池,其中包含精确所需大小的块。
malloc()
的管制,以鼓励进程之间更多的竞争...会有什么问题呢? - Tim Post