我最近阅读了Dan Grossman 撰写的优秀文章" 交易记忆/垃圾收集类比 ".一句话引起了我的注意:
理论上,垃圾收集可以通过增加空间局部性(由于对象重定位)来提高性能,但在实践中,我们为软件工程优势支付适度的性能成本.
在那之前,我的感觉一直都很模糊.一遍又一遍,你会看到GC 可以更高效的说法,所以我总是把这个概念放在脑后.然而,在读完之后,我开始怀疑.
作为衡量对GC语言影响的实验,有些人采用了一些Java程序,跟踪执行,然后用显式内存管理替换了垃圾收集.根据对Lambda最终文章的评论,他们发现GC总是较慢.虚拟内存问题使GC看起来更糟糕,因为收集器在此时经常触及比程序本身更多的内存页,因此导致大量交换.
这对我来说都是实验性的.有没有人,尤其是在C++环境中,在与显式内存管理进行比较时,是否对GC性能进行了全面的基准测试?
特别有趣的是比较各种大型开源项目如何在有或没有GC的情况下执行.以前有人听说过这样的结果吗?
编辑:请关注性能问题,而不是为什么GC存在或为什么它有益.
干杯,
卡尔
PS.如果你已经拔出了火焰喷射器:我并没有试图取消GC的资格,我只是试图找到性能问题的明确答案.
这变成了另一个带有很多"我的直觉"的火焰战争.一些变更的硬数据(论文包含细节,基准,图表等):
http://www.cs.umass.edu/~emery/pubs/04-17.pdf说:
"结论.关于垃圾收集性能影响的争议长期以来一直掩盖了它提供的软件工程效益.本文介绍了一种基于跟踪和仿真的oracular内存管理器.使用这个框架,我们使用垃圾收集和执行一系列未改变的Java基准测试.显式内存管理.比较运行时,空间消耗和虚拟内存占用,我们发现当空间充足时,垃圾收集的运行时性能可以与显式内存管理竞争,甚至可以比它高出4%.复制垃圾收集可以获得物理内存的六倍,如Lea或Kingsley分配器,以提供相当的性能."
当你有足够的内存时,复制GC变得比显式更快free()
- http://www.cs.ucsb.edu/~grze/papers/gc/appel87garbage.pdf
它还取决于您使用的语言 - Java必须在每个集合上进行大量重写(堆栈,对象,生成),并且编写一个不必在JVM中停止世界的多线程GC将是一项伟大的成就.另一方面,你几乎可以在Haskell中免费获得GC时间很少> 5%,而分配时间几乎为0.这真的取决于你在做什么以及在什么环境中.
在垃圾收集内存模型中,内存分配的成本通常要低得多,然后只是显式使用new或malloc,因为垃圾收集器通常预先分配这个内存.但是,显式内存模型也可以这样做(使用内存池或内存区域); 使内存分配的成本等于指针添加.
正如Raymond Chen和Rico Mariani指出的那样,在一般情况下,托管语言倾向于执行非托管语言.然而,在推送它之后,非托管语言可以并且最终将击败GC/Jitted语言.
同样的事情在计算机语言大战中也很明显,因为尽管C++在大多数情况下往往比Java高,但你经常会看到C++实现通过各种环节(例如对象池)来实现最佳性能.但是,垃圾收集语言往往更易于遵循和更直接的实现,因为GC更善于分配(小块)内存.
但是,GC和非GC的性能并不是最大的差别.可以说它是非GC(和引用计数)语言的确定性终结(或RIIA),它是显式内存管理的最大参数,因为它通常用于内存管理以外的目的(例如释放锁,关闭文件或窗口句柄)等等).'最近'然而C#引入了using/IDisposable构造来完成这个.
垃圾收集的另一个问题是它们使用的系统往往相当复杂以防止内存泄漏.但是,一旦发生内存泄漏,这也会使调试和跟踪变得更加困难(是的,即使是垃圾收集的语言也会有内存泄漏).
另一方面,垃圾收集语言可以在最佳时间(或大约)处理最优化的事情,而不必使开发人员承担该任务的负担.这意味着为GC语言开发可能更自然,因此您可以更专注于真正的问题.
这是我想要运行的实验:
启动一个用垃圾收集环境(如.NET或Java)编写的程序.
启动一个在非垃圾收集环境(如C或C++)中编写的类似程序.
使用程序,看看哪个程序更具响应性.
客观性的提高:让你的祖母做第3步.
引用最佳GC实现的理论性能非常好,但实际情况是,在现实世界中,用垃圾收集语言编写的程序的性能不如本机应用程序.这就是为什么性能直接转换为用户体验的大型项目仍然是用C++编写的.典型的例子是游戏编程.
另一个可能违反直觉的例子是Eclipse IDE.虽然它可以用Java编写,但必须重写整个图形子系统以产生可接受的性能.解决方案:使GUI元素围绕本机(C/C++)组件(SWT)进行轻量级包装.
我理解垃圾收集环境的绘制.内存管理很难做到.还有很多工作要做.但最重要的是:了解程序的行为方式可以让您(程序员)在尝试猜测的机器上获得优势.
Berger的论文被引用了很多,但它正在将真正的垃圾收集器与纯理论,离线,最优算法进行比较.因此,尽管它可能会告诉你一些关于理论极限,它说是很了解的表现真正的垃圾收集与真正的实现malloc
和free
.我喜欢的一项研究更好地采用了真正的程序,malloc
并free
与Hans Boehm的保守垃圾收集器进行了比较:
Ben Zorn 对保守垃圾收集的测量成本
这项研究并不完美,Zorn小心地注意到,如果程序知道他们使用的是垃圾收集器,那么有些可以更快.但是,硬数据是这样的: -在原来写入使用真实的程序malloc
和free
垃圾收集的版本在大约相同的速度运行,但需要两倍的内存.Zorn相当令人信服地说,如果你知道你有GC,你可以让事情变得更快,但是很难消除内存损失.
我从这个仔细的实验研究中学到了更多,而不是从Berger对无法实现的理想化内存管理器的研究中学到的.