除非你有编程的操作系统或嵌入式系统的部分原因任何这样做的? 我可以想像,为创建和销毁经常超载内存管理功能或引入对象池可能降低开销,但全球范围内做这些事情一些特定的类?
加成
我刚刚发现了一个重载的删除功能的错误 - 内存并不总是释放。 那是在一个不那么内存的关键应用。 此外,禁用这些重载减小通过仅〜0.5%的性能。
除非你有编程的操作系统或嵌入式系统的部分原因任何这样做的? 我可以想像,为创建和销毁经常超载内存管理功能或引入对象池可能降低开销,但全球范围内做这些事情一些特定的类?
加成
我刚刚发现了一个重载的删除功能的错误 - 内存并不总是释放。 那是在一个不那么内存的关键应用。 此外,禁用这些重载减小通过仅〜0.5%的性能。
我们重载全局new和delete操作符,我的原因是多方面的工作:
新/删除会计的想法实在是灵活和强大:可以,例如,用于记录活动线程整个调用堆栈每当ALLOC发生,以及有关汇总统计。 你可以出货在网络堆栈的信息,如果你没有足够的空间,以保持局部无论出于何种原因。 你可以在这里聚集的类型信息的只限于你的想象力(和性能,当然)。
我们使用全球重载,因为它的方便挂很多常见的调试功能存在,以及使整个应用程序扫改进的基础上,我们从这些相同的重载收集统计信息。
我们仍然使用单独的类型过于自定义的分配; 在许多情况下,加速或能力,你可以通过提供自定义的分配为如单点使用的STL数据结构的获得远远超过一般的加速,你可以从全局重载得到。
看看一些是在那里为C / C的分配器和调试系统++,你会迅速拿出这些和其他的想法:
(一两,但开创性本书编写可靠的代码 ,其中讨论了许多你可能要提供C,其中大部分仍然是非常相关的自定义分配器的原因。)
显然,如果你可以使用任何的这些优良工具,你会想这样做,而不是滚动您自己。
有些情况下,它是速度更快的情况下,更容易,更小的商业/法律麻烦,没有什么是可用于您的平台,又或只是更多的启发:挖,写一个全球性的过载。
最常见的原因重载new和delete只是检查内存泄漏和内存使用情况的统计数据。 请注意,“内存泄漏”通常被推广到内存错误。 您可以检查东西,如双删除和缓冲区溢出。
之后的用途通常是内存分配方案,如垃圾收集 ,并汇集 。
所有其他情况下都只是具体的事情,在其他的答案(记录到磁盘,内核使用)提及。
除了这里提到的其他重要的用途,如内存标签,它也迫使所有的分配在你的应用程序要经过固定块分配,这对性能和碎片产生巨大影响的唯一途径。
例如,你可能有固定的块大小的一系列存储池。 重载全球new
可以让你将所有61个字节的分配,比如说,64字节块池中,所有768-1024字节allocs到了1024B块池,所有上面的2048字节块池,以及任何超过8KB的一般粗糙的堆大。
由于固定块分配器是很大的碎片比从堆中分配无可奈何地更快,更容易,这可以强制甚至蹩脚的3D方代码从您的池分配,而不是船尾各地的地址空间。
这其中是时间和空间的关键系统,如游戏经常做。 280Z28,Meeh,和丹·奥尔森已经描述了为什么。
虚幻引擎3重载全球新和删除作为其核心内存管理系统的一部分。 有迹象表明,提供不同的功能(剖析,性能等)多个分配器,他们需要所有的分配要经过它。
编辑:对于我自己的代码,我会永远只能做它作为最后的手段。 而我的意思是我几乎肯定不会使用它。 但我个人的项目显然要小得多/非常不同的要求。
一些实时系统重载它们,以避免他们在init之后使用..
重载新的和删除能够标签添加到您的内存分配。 我每个标签系统或控制或通过中间件分配。 我可以看到,在运行时,多少每个用途。 也许是我想看到从UI或中间件的是真正使用了多少分开解析器的用法!
你也可以用它涂在分配的内存防护带。 如果当你的应用程序崩溃,/你可以看看地址。 如果你看到的内容为“0xABCDABCD”(或者不管你选择作为后卫)正在访问你没有自己的记忆。
也许以后打电话删除您可以填补这个空间与类似识别的模式。 我相信的VisualStudio确实在调试类似的东西。 没有它填补未初始化的内存0xCDCDCDCD?
最后,如果你有碎片问题,你可以用它来重定向到一个块分配器? 我不知道这是怎么往往确实是个问题。
你需要重载它们当调用new和delete在你的环境中无法正常工作。
例如,在内核编程,默认的new和delete不会因为它们依赖于用户模式库来分配内存工作。
从实用角度来看它可能只是更好地覆盖在系统库的malloc水平,因为新的运营商可能会被调用反正它。
在Linux上,你可以把你自己的版本的malloc安装的系统之一,在这里这个例子:
http://developers.sun.com/solaris/articles/lib_interposers.html
在这篇文章中,他们正试图收集性能统计信息。 但你也可以检测内存泄漏,如果你还覆盖免费。
既然你是在LD_PRELOAD的共享库这样做,你甚至不需要重新编译应用程序。
我已经看到了它在对“安全”的系统做*
的原因被要求写在它的重新分配使用的所有内存。 该方法是在每个内存块,将含有随后将被删除上覆盖零的整体块的大小开始分配额外的几个字节。
这产生了一些问题,你可能想象,但它的工作(主要是),并从一个相当大的,现有的应用程序审查每一个内存分配拯救了球队。
当然,并不是说这是一个很好的用途,但它可能是更富有想象力的在那里的一个...
*
可悲的是它是不是这么多的实际安全性安全性的外观...
用C ++编写的Photoshop插件应该重写operator new
,让他们通过Photoshop中获得的记忆。
我已经与内存映射文件来完成它,以便写入到内存中的数据会自动也保存到磁盘。
它也可用于在特定的物理地址,如果你有存储器映射的IO设备,或有时如果需要分配连续的存储器的特定块返回存储器。
但它是作为一个调试功能做了99%的时间来登录多久,在那里,当内存被分配和释放。
这其实很常见的游戏分配了一个巨大的从系统内存块,然后提供自定义的分配通过重载new和delete。 一个大原因是,游戏机有一个固定的内存大小,使得无论泄漏和碎片大的问题。
通常(至少在一个封闭的平台)默认堆操作都配有缺乏控制和缺乏反省的。 对于许多应用,这并不重要,但对于游戏中的固定内存的情况下所增加的控制和反省运行稳定都是非常重要的。
它可以是一个很不错的技巧为你的应用程序能够通过比随机崩溃别的事情内存不足的情况作出反应。 要做到这一点您的new
可以是一个简单代理到默认new
映入它的失败,释放了一些东西,并再次尝试。
最简单的方法是在启动时预留的内存空白块为根本目的。 您还可能有一些高速缓存可以进军 - 的想法是一样的。
当第一次分配失败踢,你还有时间来提醒你的用户对内存不足的情况(“我就可以长一点生存,但你可能要保存您的工作并关闭一些其他应用程序”),你的状态保存到磁盘上,切换到生存模式,或其他任何有意义您的环境。
最常见的使用情况下,可能是泄漏检查。
另一种使用情况是,当你在你的环境中进行内存分配的具体要求,这是不是你正在使用的标准库纳一样,例如,你需要保证内存分配锁定自由多线程环境。
正如许多人已经指出,这通常是在性能关键应用行为,或能够控制内存对齐或跟踪你的记忆。 游戏中通常使用自定义的内存管理,特别是针对特定平台/控制台时。
这是一个相当不错的关于这样的一种方式博客文章和一些推理。