HotSpot JVM中的动态tenuring阈值调整如何工作?

9

据我目前所知:

  • 对象被分配在Eden空间,如果它们经过一次minor GC存活下来,它们就会晋升到一个Survivor空间之一。
  • 对于进一步的minor GC,那些在minor GC中存活下来的对象会在两个survivor空间之间交换。在此期间,对象的单个年龄将随着每个minor GC而增加。
  • 达到特定的tenuring threshold的对象将被提升到tenured space(老年代)。
  • 您可以设置InitialTenuringThreshold(因为它是“initial”而不是“min”)和MaxTenuringThreshold(最大值:15)。然而,JVM会根据实际使用的survivor空间和desired survivor空间(我认为是每次major GC后)调整actual tenuring threshold。
  • 可以使用“TargetSurvivorRatio”JVM参数来更改所需空间,默认情况下为最大survivor空间的50%。

我的问题是:

  • JVM调整实际tenuring阈值是基于什么进行调整的?
  • 当JVM更改实际tenuring阈值后,所有对象年龄队列会发生什么情况?例如:
    • timeStamp1: JVM当前实际tenuring阈值为15。每个年龄段都有对象分布。
    • timeStamp2: JVM已将实际tenuring阈值调整为5。那么从timeStamp1开始,所有年龄n>5的对象会发生什么情况?

目前还没有找到相关文档。

1个回答

1

我对JDK的代码库并不是很了解,但我相信大部分你的答案都会涉及到我提到的类。我只是根据粗略阅读进行猜测,并非常乐意听到更正。

问题1:

根据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)。

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

g1CollectorPolicy.hpp 中解释了 young_list_target_length 的更新:

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);

我没有研究过这个模型,但我猜这可能是你的答案:在足以保持所需幸存者大小(如 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();

我理解这个阈值将在GC运行之前更新。如果是这样的话,当访问幸存区域中的活动对象时,所有具有object.age > newAge的对象都将被提升(包括那些在timestamp1时age < threshold但现在超过它的对象)。

希望这有点意义。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接