2011-04-05 59 views
6

如果无法分配请求的内存,C++程序可以定义和设置一个new_handler(),应该从内存分配函数(如operator new())调用该函数。除了垃圾收集之外,还有什么可以在C++中使用“new_handler”?

自定义new_handler()的一个用途是dealing with C++ implementations that don't throw an exception on allocation failure。另一个用途是在实现垃圾收集的系统上启动垃圾收集。

还有什么其他用途的自定义new_handler()

回答

7

与垃圾收集应用程序类似,您可以使用新处理程序释放您可能保留的任何缓存数据。

假设您正在缓存从磁盘读取的某些资源数据或某些计算的中间结果。这是您可以随时重新创建的数据,因此当新的处理程序被调用(表示您已经用完堆)时,可以释放缓存数据的内存,然后从新处理程序返回。希望new现在可以进行分配。

在很多情况下,虚拟内存可以达到同样的目的:如果您有足够的虚拟地址空间,您可以简单地让您的缓存数据换出到磁盘。在32位系统上,情况并非如此,因此新处理程序是一个有趣的选项。许多嵌入式系统将面临类似的限制。

6

在大多数我工作的服务器,在new_handler 之前释放 预分配的块(所以未来的新的也不会失败)记录消息(记录器使用动态内存),并中止。 这确保了内存不足错误被正确记录了 (而不是过程只是“消失”,并且错误 消息到cerr,它已连接到/dev/null)。

在编辑器等应用程序中,有可能将部分缓冲区的部分溢出到磁盘上,然后继续;如果 new_handler返回,operator new应该重试 分配,并且如果new_handler释放了足够的内存,则分配可能成功(如果不是,则new_handler将再次调用,以免为空)甚至更多)。

1

我从来没有使用过它 - 太多的操作系统会授予虚拟内存和SIGSEGV或类似的,如果他们以后不能提供它,所以这是不是一个好主意,使一个系统,依赖于内存耗尽容忍:它通常在C++之外。尽管如此,如果您开发的系统可以/必须依赖它,我可以轻松想象一种情况,即某些实时数据正在流入您的进程中的队列中,并且您正在处理它并编写/发送结果尽可能快(例如视频硬件流媒体视频,以重新压缩到磁盘/网络)。如果你到了无法再储存的阶段,你只需要放弃一些,但是如何知道它什么时候变得糟糕?设置一个任意的限制会是一种愚蠢的行为,特别是如果你的软件是用于只存在于这个任务中的嵌入式环境/盒子的话。而且,您可能不应该在具有任何类型的基于硬盘的交换内存的系统上随便使用这样的功能,就好像您已经进入交换一样,您的吞吐率会从此以后变得惨不忍睹。但是 - 通过警告 - 在一段时间内丢弃数据包可能会很有用,直到你赶上。也许在队列缓冲区中放置每一个第N帧比在队列的后面或前面放置一块更不明显。无论如何,丢弃队列中的数据可能是一种理智的应用程序级别的使用(与内存子系统不同),用于这样的事情....