在什么情况下垃圾收集比手动内存管理更有效? (这里的手册可能意味着在C中使用malloc和free,或者使用C ++推广的更清晰的RAII和智能指针技术)
我喜欢垃圾收集如何从编写软件中消除一些偶然的复杂性,但我更加高兴的是RAII和智能指针如何消除这种复杂性,同时还可以处理除内存以外的资源,确定性,并提供性能保证和整体效率更高。所以我想我可以安全地忽略垃圾收集。但是,我注意到人们一直在说垃圾收集比C ++中使用的紧密资源管理更快,例如当有大量额外内存可用时。
那么什么时候垃圾收集完全可以胜过手动内存管理?我喜欢RAII和智能指针,但如果速度更快,很乐意接受垃圾收集作为另一种工具。
答案 0 :(得分:13)
从不,我可以证明这一点。
首先,让我们假设我们在任何一种情况下都使用最好的算法。使用次优算法可以证明什么。
其次,让我们假设最好的GC算法使用时间T0...Tn
来决定是否应该在某个时刻释放内存分配i
。总数为Σ(Ti)
现在,存在使用相同GC算法的等效手动内存管理算法,但仅考虑已手动标记为已释放的内存块。因此,运行时间为Σ(δiTi)
(当块i未被释放时δi= 0,当它被释放时为= 1)。
显然,Σ(δiTi) ≤ Σ(Ti)
:有一种手动算法,严格来说不比GC算法差。
这与其他答案形成鲜明对比?
答案 1 :(得分:11)
GC缺点:
对于perf来说,这是一个灌篮,GC不费力地轻松击败堆分配器。 Rico Mariani和Raymond Chen之间的汉语词典编程比赛经常被引用,概述is here。雷蒙德的C ++程序最终赢了,但只是在重写了几次并放弃了标准的C ++库之后。
答案 2 :(得分:2)
我知道有一个特殊的场景,当GC指针比传统的C ++(即不是C ++ / CLR,而不是C ++ / CLR)实现时,GC指针比智能指针(引用计数指针)要快得多。 Mark-Sweep之后的内存,我们正试图在这里尽可能多地比较苹果和苹果)假设GC使用相同的底层堆内存管理器。当你的对象分配时间明显超过对象创建时间时。
示例包括排序,数组反转等。
请参阅此处查看more info on my test with a GC framework I implemented using traditional C++ vs引用计数指针。阵列反转测试的结果是GcString比ref count String快16.5倍。
这可能归因于引用计数指针中缓慢的总线锁定语义(除非您的目标是纯单线程应用程序,因此线程安全需要锁定)。根据我在传统C ++中实现高性能精确GC的经验,我可以说使用GC vs 'manual'(根据OP的手册定义)内存管理(即ie)有更多机会进行优化智能指针)。