如果无法分配请求的内存,C ++程序可以定义和设置应该从内存分配函数调用的new_handler()
,如operator new()
。
自定义new_handler()
的一种用途是dealing with C++ implementations that don't throw an exception on allocation failure。另一个用途是在实现垃圾收集的系统上启动垃圾收集。
自定义new_handler()
的其他用途是什么?
答案 0 :(得分:7)
与垃圾收集应用程序类似,您可以使用新处理程序释放您可能保留的任何缓存数据。
假设您正在缓存从磁盘读取的某些资源数据或某些计算的中间结果。这是您可以随时重新创建的数据,因此当调用新处理程序(表示您已用完堆)时,您可以释放缓存数据的内存,然后从新处理程序返回。希望new
现在能够进行分配。
在许多情况下,虚拟内存可以起到同样的作用:如果你有足够的虚拟地址空间,你可以简单地让你的缓存数据换成磁盘。在32位系统上,实际情况并非如此,因此新处理程序是一个有趣的选项。许多嵌入式系统将面临类似的限制。
答案 1 :(得分:6)
在我工作过的大多数服务器上,new_handler都被释放了
之前预先分配的块(所以未来新的不会失败)
记录消息(记录器使用动态内存)并中止。
这确保了正确记录了内存不足错误
(而不是过程只是“消失”,错误
发送到cerr
的{{1}}消息。
在编辑等应用程序中,有可能 将部分缓冲区的部分溢出到磁盘,然后继续;如果 new_handler返回,operator new应该重试 分配,如果new_handler释放了足够的内存, 分配可能会成功(如果没有,则为new_handler 将被再次召唤,甚至可以释放更多)。
答案 2 :(得分:1)
我从来没有将它用于任何事情 - 太多的操作系统会授予虚拟内存和SIGSEGV或类似的,如果他们以后不能提供它,那么建立一个依赖于内存耗尽容忍的系统并不是一个好主意:它通常不在C ++手中。尽管如此,如果您为可以/必须依赖的系统开发,我可以很容易地想象出一些实时数据在流程中流入队列的情况,并且您正在处理它并写入/发送结果尽可能快(例如视频硬件流视频重新压缩到磁盘/网络)。如果你到了无法再存储的阶段,你只需要放弃一些,但是你怎么知道它什么时候变坏?设置任意限制将是一种愚蠢的行为,特别是如果您的软件用于仅存在执行此任务的嵌入式环境/盒子。并且,您可能不应该在具有任何类型的基于硬盘的交换内存的系统上随意使用这样的功能,就好像您已经进入交换一样,您的吞吐率将永远是悲惨的。但是 - 经过警告 - 将数据包丢弃一段时间直到你赶上来可能是有用的。或许通过排队缓冲区丢弃每个第N帧比在队列的后面或前面丢弃一个块更不明显。无论如何,丢弃队列中的数据可能是一个理智的应用程序级使用(与内存子系统不同),就像这样......