动态终身阈值调整如何在HotSpot JVM中工作?

Ben*_*ser 9 java garbage-collection jvm heap-memory jvm-hotspot

到目前为止,我知道:

  • 物体在伊甸园空间中分配,如果它们在次要集合中存活,它们将被提升为幸存者空间之一
  • 对于进一步的小型集合,在两个幸存者空间之间交换存在次要集合的对象.在这个对象中,每个次要集合的个体年龄都在增加.
  • 达到特定期限阈值的对象将被提升到终身空间(旧一代).
  • 您可以设置InitialTenuringThreshold(因为它表示它是'initial'而不是'min')和MaxTenuringThreshold(MaxValue:15).然而,JVM根据实际使用的幸存者空间和期望的幸存者空间调整实际的终身临界阈值(我认为每次重大收集后).
  • 可以使用" TargetSurvivorRatio "JVM参数更改所需的空间,默认情况下为最大幸存者空间的50%.

我的问题是:

  • 关于jvm到底调整实际的临界阈值究竟是什么.
  • 在jvm更改实际的tenuring阈值之后,所有对象年龄队列会发生什么.例如:
    • timeStamp1:由jvm设置的当前实际任期为15.每个年龄段都有分布的对象.
    • timeStamp2:JVM已经调整实际tenuring门槛5. N> 5的由年龄全部对象现在会发生什么timeStamp1

没有找到任何关于此的文档.

Gal*_*rro 1

我距离 JDK 代码库方面的专家还很远,但我相信您的大多数答案都将围绕我提到的类。我通过粗略的阅读进行了疯狂的猜测,并且很高兴听到更正。

问题一:

根据http://hg.openjdk.java.net/jdk8/jdk8/hotspot/file/87ee5ee27509/src/share/vm/gc_implementation/shared/ageTable.cpp L81和接下来的(compute_tenuring_threshold),JVM将迭代每个年龄并将该年龄的物体的大小相加。一旦它超过了desired_survivor_size,它就会停止并假设它到达的最后一个年龄作为候选的新阈值。选择的新阈值是 min(candidateAge, MaxTenuringThreshold)

在G1中从http://hg.openjdk.java.net/jdk8/jdk8/hotspot/file/87ee5ee27509/src/share/vm/gc_implementation/shared/g1CollectorPolicy.cpp调用compute_tenuring_threshold ,它根据ceil(_young_list_target_length选择_max_survivor_regions /SurvivorRatio),然后调用上面的compute_..方法。

young_list_target_length 在 g1CollectorPolicy.hpp 中更新,如下所述:

587   // Update the young list target length either by setting it to the
588   // desired fixed value or by calculating it using G1's pause
589   // prediction model. If no rs_lengths parameter is passed, predict
590   // the RS lengths using the prediction model, otherwise use the
591   // given rs_lengths as the prediction.
592   void update_young_list_target_length(size_t rs_lengths = (size_t) -1);
Run Code Online (Sandbox Code Playgroud)

我没有研究模型,但我想这会回答你的问题:在较低的年龄数足以保持所需的幸存者大小后触发阈值变化(AFAIK在这里解释http://www.oracle.com/ technetwork/java/javase/tech/vmoptions-jsp-140102.html)。新阈值是根据给定/预测的 RS 长度选择的。

问题2:

在 g1CollectorPolicy.cpp 中检查这一点,就在新的收集暂停开始时:

839   // We only need to do this here as the policy will only be applied
840   // to the GC we're about to start. so, no point is calculating this
841   // every time we calculate / recalculate the target young length.
842   update_survivors_policy();
Run Code Online (Sandbox Code Playgroud)

据我所知,阈值将在GC 运行之前更新。如果是这种情况,当访问幸存者区域中的活动对象时,所有 object.age > newAge 的对象都将被保留(包括那些在 timestamp1 时年龄 < 阈值但现在超过它的对象)。

我希望这是有道理的。