【问题标题】:MaxTenuringThreshold - how exactly it works?MaxTenuringThreshold - 它究竟是如何工作的?
【发布时间】:2012-11-24 17:07:53
【问题描述】:

我们知道主要内存域很少:Young、Tenured(Old gen)和 PermGen。

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

MaxTenuringThreshold 防止对象过早地最终复制到 OldGen 空间。它非常清晰易懂。

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

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

【问题讨论】:

    标签: java garbage-collection


    【解决方案1】:

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

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

    Object的旅程有以下模式:

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

    实际的tenuring threshold由JVM动态调整,但MaxTenuringThreshold设置了一个上限。

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

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

    【讨论】:

    • 您没有回答更改 MaxTenuringThreshold 会如何影响 GC。如果我将其设置为 6 会怎样? 15?会有什么不同?
    • MaxTenuringThreshold 的最大(有效)值是否记录在任何地方?
    • 您不应设置超过 15 的值。参考:support.oracle.com/knowledge/Middleware/1283267_1.html
    【解决方案2】:

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

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

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

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

    【讨论】:

      猜你喜欢
      • 2020-05-16
      • 2014-04-30
      • 1970-01-01
      • 1970-01-01
      • 2020-06-04
      • 2016-02-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-26
      相关资源
      最近更新 更多