Java GCs开销:如果你有10mb或10g *引用的*对象,这有关系吗?

时间:2012-01-25 15:24:39

标签: java performance garbage-collection nio

GC必须检查并找出可以收集的对象。我的问题是,是否有太多要检查的对象会导致GC开销,或者某种程度上GC是否足够智能以避免必须遍历所有对象以找出哪个对象不再被引用?

4 个答案:

答案 0 :(得分:3)

是的,它对mark-and-sweep collector你有多少个物体很重要。至于那些对象的 size ,这也很重要:如果需要压缩10GB的东西而不是10MB的东西,压缩收集器还有更多的工作要做。

话虽如此,现代垃圾收集器非常复杂(它们在多个堆上运行,在后台运行,可以使用多个核等)。它们也是高度可配置的。此外,典型的JVM配备了多个垃圾收集器。

因此很难对这样的一般问题给出有意义的,精确的答案。

答案 1 :(得分:2)

优化此类事情的一种方式是Generational Garbage Collection的概念。 (见第4节)。显然,自1.2以来,Java已经有了世代收藏。

这意味着通常较新的物体可能会更快死亡,称为“婴儿死亡率”。这些较新的对象被置于更积极地收集的一代中。如果一个物体已经存在了一个小时,它可能会在另外5分钟左右被放置在一个收集频率低于新物体的一代中。如果一个物体在更频繁收集的区域中存活了一段时间,它将被提升为频繁收集的一代。

这使您无法查看每次扫描的所有活动对象。

答案 2 :(得分:1)

必须遍历所有活动对象以确定是否仍使用对象。 G1收集器有1 MB兆字节对象(它知道1 MB内的所有引用),但性能大致相同。

当您进入多GB解决方案时,一个选项是使用您自己管理的堆内存。或者您可以使用Zing之类的解决方案,它可以处理数十GB的堆而不会出现明显的暂停。

答案 3 :(得分:1)

这取决于使用哪种GC算法,在标记扫描的情况下,它确实很重要,因为标记扫描需要使用枚举来识别GC的根。 Here is link on how mark-sweep works