MaxTenuringThreshold - 它究竟是如何工作的?

时间:2012-11-24 17:07:53

标签: java garbage-collection

我整天都在谷歌搜索。但对我来说仍然不太清楚,所以这个问题可能听起来有些妄想。

嗯..我们知道主存储域很少。 Young,Tenured(Old gen)和PermGen。

Young域名分为Eden和Survivor(其中两个)。 OldGen用于存活物体 关于MaxTenuringThreshold - 它使对象不会过早地被复制到OldGen空间 它非常清晰易懂。

但是那个“MaxTenuringThreshold”...... - 它究竟是如何起作用的? 垃圾收集器如何处理这些仍然存活到MaxTenuringThreshold的对象以及以什么方式存在?它们位于何处?
对象被复制回Survivor空间以进行垃圾收集......或者它以其他方式发生?

没有找到任何好的解释,所以我会非常感谢任何有用的链接或解释。

2 个答案:

答案 0 :(得分:57)

Java堆中的每个对象都有一个垃圾收集(GC)算法使用的标头。年轻的空间收集器(负责对象升级)使用此标头中的一些位来跟踪幸存的集合对象的数量(32位JVM使用4位,64位可能更多)

在年轻空间收集期间,每个对象都被复制。可以将对象复制到生存空间之一(在年轻GC之前为空)或旧空间。对于每个被复制的对象,GC算法会增加它的年龄(存活的数量),如果年龄高于当前终身阈值,它将被复制(提升)到旧空间。如果生存空间变满(溢出),也可以直接将对象复制到旧空间。

对象的旅程有以下模式:

  • 在伊甸园分配
  • 由于年轻的GC从伊甸园复制到生存空间
  • 由于年轻的GC而从生存复制到(其他)生存空间(这可能会发生几次)
  • 由于年轻的GC(或完整的GC)而从生存(或可能的伊甸园)升级到旧空间

实际的终身阈值由JVM动态调整,但MaxTenuringThreshold设置了它的上限。

如果设置MaxTenuringThreshold = 0,则会立即提升所有对象。

我有关于java垃圾收集的few articles,你可以在那里找到更多细节。

答案 1 :(得分:14)

(免责声明:仅涵盖HotSpot VM)

正如Alexey所述,实际使用的终身阈值是由JVM动态确定的。设置它没什么价值。对于大多数应用程序,默认值15将足够高,因为通常更多对象在集合中存活。 当许多物体在集合中存活下来时,幸存者空间直接溢出到旧的。这称为过早促销和问题指标。但是,通过调整MaxTenuringThreshold很少能解决这个问题。

在这些情况下,有时可能会使用SurvivorRatio来增加幸存者空间的空间,从而使终身实际工作。 然而,大多数情况下,扩大年轻一代是唯一的好选择(从配置的角度来看)。 如果您从编码角度来看,您应该避免多余的对象分配,以使终身工作按照设计进行。

准确回答您的要求: 当一个对象达到其JVM确定的tenuring阈值时,它将被复制到old。在此之前,它将被复制到空的幸存者空间。已经存活了一段时间但在达到阈值之前被解除引用的对象可以非常有效地从幸存者中清除。