繁体   English   中英

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

[英]MaxTenuringThreshold - how exactly it works?

我们知道很少有主内存域:Young、Tenured(老一代)和 PermGen。

  • Young域分为Eden和Survivor(有两种)。
  • OldGen 用于幸存的对象。

MaxTenuringThreshold 可防止对象过早地最终复制到 OldGen 空间。 这是非常清楚和易于理解的。

但它是如何工作的? 垃圾收集器如何处理这些在 MaxTenuringThreshold 之前仍然存活的对象?以什么方式? 它们位于何处?

对象正在被复制回 Survivor 空间进行垃圾收集......还是以其他方式发生?

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

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

Object 的旅程具有以下模式:

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

实际的任期阈值由 JVM 动态调整,但 MaxTenuringThreshold 对其设置了上限。

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

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

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

正如 Alexey 所说,实际使用的任期阈值是由 JVM 动态确定的。 设置它的价值很小。 对于大多数应用程序,默认值 15 已经足够高了,因为通常会有更多的对象在集合中存活下来。 当许多对象在集合中幸存下来时,幸存者空间直接溢出到旧的。 这称为过早提升和问题的指标。 然而,它很少可以通过调整 MaxTenuringThreshold 来解决。

在这些情况下,有时可能会使用 SurvivorRatio 来增加幸存者空间中的空间,从而使任期真正起作用。 然而,通常扩大年轻代是唯一好的选择(从配置的角度来看)。 如果您是从编码的角度来看,您应该避免过多的对象分配,让任期按设计工作。

准确回答您的问题:当一个对象达到其 JVM 确定的任期阈值时,它会被复制到旧的。 在此之前,它将被复制到空的幸存者空间。 已经存活一段时间但在达到阈值之前被取消引用的对象会非常有效地从幸存者中清除。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM