【问题标题】:What can "new_handler" be used for in C++ besides garbage collection?除了垃圾收集,“new_handler”在 C++ 中还能用来做什么?
【发布时间】:2011-07-29 18:01:07
【问题描述】:
【问题讨论】:
标签:
c++
visual-c++
error-handling
memory-management
【解决方案1】:
与垃圾收集应用程序类似,您可以使用新的处理程序来释放您可能保留的任何缓存数据。
假设您正在缓存从磁盘读取的一些资源数据或一些计算的中间结果。这是您可以随时重新创建的数据,因此当调用新的处理程序时(表示您的堆已用完),您可以为缓存的数据释放内存,然后从新的处理程序返回。希望new 现在能够进行分配。
在许多情况下,虚拟内存可以达到相同的目的:如果您有足够的虚拟地址空间,您可以简单地将缓存数据换出到磁盘上。在 32 位系统上,实际情况不再如此,因此新的处理程序是一个有趣的选项。许多嵌入式系统将面临类似的限制。
【解决方案2】:
在我工作过的大多数服务器上,new_handler 被释放
一个预先分配的块(所以未来的新块不会失败)之前
记录一条消息(记录器使用动态内存)并中止。
这确保了正确记录内存不足错误
(而不是过程只是“消失”,出现错误
消息到cerr,它连接到/dev/null)。
在编辑器等应用程序中,可能
将一些缓冲区的部分溢出到磁盘,然后继续;如果
new_handler 返回,operator new 应该重试
分配,如果 new_handler 释放了足够的内存,
分配可能成功(如果没有成功,new_handler
将再次被调用,可能会释放更多)。
【解决方案3】:
我从来没有将它用于任何事情 - 太多的操作系统会授予虚拟内存和 SIGSEGV 或类似的,如果他们以后不能提供的话,所以创建一个依赖于内存耗尽容忍的系统不是一个好主意:它通常不在 C++ 的控制范围内。尽管如此,如果您为一个可以/必须依赖它的系统开发,我可以很容易地想象一些实时数据被流式传输到您的流程中的队列中,并且您正在处理它并写入/发送结果尽可能快(例如,用于重新压缩到磁盘/网络的视频硬件流视频)。如果你到了不能再储存的阶段,你只需要放下一些,但你怎么知道它什么时候变得那么糟糕呢?设置任意限制有点愚蠢,特别是如果您的软件用于仅存在执行此任务的嵌入式环境/盒子。而且,您可能不应该在具有任何类型的基于硬盘的交换内存的系统上随意使用这样的功能,因为如果您已经进入交换状态,您的吞吐率将永远是悲惨的。但是 - 除了警告 - 在你赶上之前丢弃数据包一段时间可能会很有用。可能每第 N 帧通过排队缓冲区丢弃比在队列的后面或前面丢弃一个块更不可见。无论如何,对于这样的事情,从队列中丢弃数据可能是一个理智的应用程序级使用(不同于内存子系统内)......