我对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但现在超过它的对象)。
希望这有点意义。