.NET:什么是典型的垃圾收集器开销?

时间:2010-02-15 16:37:17

标签: c# .net clr

在GC上花费了5%的执行时间? 10%? 25%?

感谢。

8 个答案:

答案 0 :(得分:10)

正如其他人所说,这取决于。但是,只是为了你的阅读:

另外,我的问题是 - 你为什么担心开销(或者你只是从学术角度感到好奇)?如果您认为垃圾收集器会影响应用程序的性能,请询问相关情况,您可能会得到更好的响应。否则,从垃圾收集器(从性能的角度来看)有更重要的事情要担心 - 第一个是你自己的代码/算法/等。

答案 1 :(得分:3)

完全取决于应用程序。垃圾收集是根据需要完成的,因此越频繁地分配大量内存,后来变成垃圾,它就越频繁地运行。

如果您事先分配所有内容并且从不分配任何新对象,它甚至可以低至0%。

在典型的应用程序中,我认为答案非常接近于垃圾收集器花费的时间。

答案 2 :(得分:3)

观看红门的视频here。 我遇到过的最好的GC探索。

答案 3 :(得分:2)

This blog post对这个领域进行了一次有趣的调查。

海报的结论?对于他的例子,开销几乎可以忽略不计。

  

因此GC堆非常快,以至于在真正的程序中,即使在紧密的循环中,你也可以使用闭包和委托,甚至不需要考虑它(或甚至几纳秒的思考)。与往常一样,在干净,安全的设计上工作,然后剖析以找出开销的位置。

答案 4 :(得分:2)

开销差异很大。将问题域简化为“典型场景”并不切实可行,因为GC(以及相关函数,如终结)的开销取决于几个因素:

  • 您的应用程序使用的GC风格(影响GC中线程可能被阻止的方式)。
  • 您的分配配置文件,包括您分配的频率(当分配请求需要更多内存时GC自动触发)和对象的生命周期配置文件(第0代集合最快,第2代集合较慢,如果您引发了大量的内容你的管理费用会增加2个。)
  • 可终结对象的生命周期配置文件,因为在它们有资格收集之前,它们必须完成终结器。

可以分析各个点对每个相关轴的影响(并且可能有更多相关领域,我不记得我的头脑) - 所以问题实际上是“你怎么能减少那些与“常见情景”相关的轴?“

基本上,正如其他人所说,这取决于。或者,“足够低,你不应该担心它,直到它出现在探查器报告上。”

答案 5 :(得分:1)

是的,垃圾收集器将花费大约X%的时间来收集所有应用程序的平均值。但这并不一定意味着时间是开销。 对于开销,您实际上只能计算在非托管平台上释放等量内存后剩下的时间。

考虑到这一点,实际的开销是否定,但垃圾收集器将节省时间,批量释放几个内存块。这意味着更少的上下文切换和整体效率的提高。

此外,从.Net 4开始,垃圾收集器在不同的线程上完成了很多工作,不会中断当前运行的代码。随着我们越来越多地使用多核机器,核心甚至可能偶尔闲置,这是一个大问题。

答案 6 :(得分:1)

在本机C / C ++中,由于找到了一个大小合适的可用内存块,有时会出现分配内存的成本,而且还有一个无法释放内存的成本必须将释放的内存链接到正确的块列表,并将小块组合成大块。

在.NET中,分配新对象非常快,但是在垃圾收集器运行时需要支付成本。 然而,对于垃圾收集的成本,短期对象尽可能接近免费。

我一直发现,如果垃圾收集的成本对您来说是个问题,那么您的软件设计可能会遇到更大的问题。分页可能是个大问题任何GC,如果你没有足够的物理RAM,那么你可能无法将所有数据放入RAM并依赖操作系统来提供虚拟内存。

答案 7 :(得分:0)

真的可以变化。看看我写的这个演示short-but-complete程序:

http://nomorehacks.wordpress.com/2008/11/27/forcing-the-garbage-collector/

显示了大型gen2垃圾收集的效果。