当前位置:  开发笔记 > 编程语言 > 正文

关于GC与显式内存管理性能的任何硬数据?

如何解决《关于GC与显式内存管理性能的任何硬数据?》经验,为你挑选了4个好方法。

我最近阅读了Dan Grossman 撰写的优秀文章" 交易记忆/垃圾收集类比 ".一句话引起了我的注意:

理论上,垃圾收集可以通过增加空间局部性(由于对象重定位)来提高性能,但在实践中,我们为软件工程优势支付适度的性能成本.

在那之前,我的感觉一直都很模糊.一遍又一遍,你会看到GC 可以更高效的说法,所以我总是把这个概念放在脑后.然而,在读完之后,我开始怀疑.

作为衡量对GC语言影响的实验,有些人采用了一些Java程序,跟踪执行,然后用显式内存管理替换了垃圾收集.根据对Lambda最终文章的评论,他们发现GC总是较慢.虚拟内存问题使GC看起来更糟糕,因为收集器在此时经常触及比程序本身更多的内存页,因此导致大量交换.

这对我来说都是实验性的.有没有人,尤其是在C++环境中,在与显式内存管理进行比较时,是否对GC性能进行了全面的基准测试?

特别有趣的是比较各种大型开源项目如何在有或没有GC的情况下执行.以前有人听说过这样的结果吗?

编辑:请关注性能问题,而不是为什么GC存在或为什么它有益.

干杯,

卡尔

PS.如果你已经拔出了火焰喷射器:我并没有试图取消GC的资格,我只是试图找到性能问题的明确答案.



1> viraptor..:

这变成了另一个带有很多"我的直觉"的火焰战争.一些变更的硬数据(论文包含细节,基准,图表等):

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.这真的取决于你在做什么以及在什么环境中.


@viraptor:1.你比较了错误的数字.看看:F#哈希表0.75s,Haskell Map 7.5s.你的理论是对的.您在OCaml/F#/ SML中也会得到相同的结果,这是由纯函数数据结构的渐近更高的缓存复杂性引起的.3.无关紧要的哈希表不是纯粹的功能数据结构.4.同样无关紧要的是,你正在讨论禁用GHC的GC以解决与哈希表有关的错误,这与关于纯功能数据结构的这个对话无关.
@Jon Harrop:"由于纯功能数据结构的性能相对较差"叹息...... [引证需要]即使是愚蠢的基准测试,例如对于aloth的语言枪战显示haskell,lisp和ocaml的范围比极端慢3-5倍调整C算法.
@viraptor - 上面提到的论文(由我自己和当时的学生Matthew Hertz)实际指向技术报告版本.最终版本(出现在2005年OOPSLA)为:http://portal.acm.org/citation.cfm?doid=1094811.1094836和http://www.cs.umass.edu/~emery/pubs/gcvsmalloc. PDF格式
@JonHarrop我发现特定的比较很奇怪。当然-这些算法以相同的输出(排序列表)以不同的方式(就地-vs-复制)执行操作。一个将比另一个慢。您可以在C语言中编写一个副本,并在Haskell中就地编写一个副本(使用未装箱的矢量),然后反转时间。我认为这与GC没有任何关系,因为就地解决方案完全避免了分配。

2> Jasper Bekke..:

在垃圾收集内存模型中,内存分配的成本通常要低得多,然后只是显式使用new或malloc,因为垃圾收集器通常预先分配这个内存.但是,显式内存模型也可以这样做(使用内存池或内存区域); 使内存分配的成本等于指针添加.

正如Raymond Chen和Rico Mariani指出的那样,在一般情况下,托管语言倾向于执行非托管语言.然而,在推送它之后,非托管语言可以并且最终将击败GC/Jitted语言.

同样的事情在计算机语言大战中也很明显,因为尽管C++在大多数情况下往往比Java高,但你经常会看到C++实现通过各种环节(例如对象池)来实现最佳性能.但是,垃圾收集语言往往更易于遵循和更直接的实现,因为GC更善于分配(小块)内存.

但是,GC和非GC的性能并不是最大的差别.可以说它是非GC(和引用计数)语言的确定性终结(或RIIA),它是显式内存管理的最大参数,因为它通常用于内存管理以外的目的(例如释放锁,关闭文件或窗口句柄)等等).'最近'然而C#引入了using/IDisposable构造来完成这个.

垃圾收集的另一个问题是它们使用的系统往往相当复杂以防止内存泄漏.但是,一旦发生内存泄漏,这也会使调试和跟踪变得更加困难(是的,即使是垃圾收集的语言也会有内存泄漏).

另一方面,垃圾收集语言可以在最佳时间(或大约)处理最优化的事情,而不必使开发人员承担该任务的负担.这意味着为GC语言开发可能更自然,因此您可以更专注于真正的问题.


你似乎都在假设单线程程序.池分配器在多线程程序中分解,而GC不分解.
Chen和Mariani的例子肯定不是**的一般情况.相反,它是一个非常特殊(尽管通常发生)的问题,其中.NET由于纯粹的技术原因而表现更好.托管语言在类似方案中没有先验的理由表现更好.
+1 @ Jasper,有一个警告 - IDisposable与确定性终结无关.它用于清理外部资源,对托管内存收集没有直接影响.

3> Waylon Flinn..:

这是我想要运行的实验:

    启动一个用垃圾收集环境(如.NET或Java)编写的程序.

    启动一个在非垃圾收集环境(如C或C++)中编写的类似程序.

    使用程序,看看哪个程序更具响应性.

客观性的提高:让你的祖母做第3步.

引用最佳GC实现的理论性能非常好,但实际情况是,在现实世界中,用垃圾收集语言编写的程序的性能不如本机应用程序.这就是为什么性能直接转换为用户体验的大型项目仍然是用C++编写的.典型的例子是游戏编程.

另一个可能违反直觉的例子是Eclipse IDE.虽然它可以用Java编写,但必须重写整个图形子系统以产生可接受的性能.解决方案:使GUI元素围绕本机(C/C++)组件(SWT)进行轻量级包装.

我理解垃圾收集环境的绘制.内存管理很难做到.还有很多工作要做.但最重要的是:了解程序的行为方式可以让您(程序员)在尝试猜测的机器上获得优势.


@Jon:糟糕的例子:VS2010比2008年感觉更糟,反应更差.
@harto肯定是"硬数据".这是关于感知性能的"硬数据".如果您更关心实际表现,请拿出秒表.如果没有Java的性能问题,SWT项目将不存在,.NET无法避免失败.你曾经玩过使用GC语言编写的游戏吗?如果是这样,你真的可以说它与同类非GC游戏一样响应吗?每个人都喜欢吹动GC号角.没有人喜欢运行GC应用程序.

4> Norman Ramse..:

Berger的论文被引用了很多,但它正在将真正的垃圾收集器与纯理论,离线,最优算法进行比较.因此,尽管它可能会告诉你一些关于理论极限,它说是很了解的表现真正的垃圾收集与真正的实现mallocfree.我喜欢的一项研究更好地采用了真正的程序,mallocfree与Hans Boehm的保守垃圾收集器进行了比较:

Ben Zorn 对保守垃圾收集的测量成本

这项研究并不完美,Zorn小心地注意到,如果程序知道他们使用的是垃圾收集器,那么有些可以更快.但是,硬数据是这样的: -在原来写入使用真实的程序mallocfree垃圾收集的版本在大约相同的速度运行,但需要两倍的内存.Zorn相当令人信服地说,如果你知道你有GC,你可以让事情变得更快,但是很难消除内存损失.

我从这个仔细的实验​​研究中学到了更多,而不是从Berger对无法实现的理想化内存管理器的研究中学到的.

推荐阅读
贴进你的心聆听你的世界
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有