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

时间:2014-03-12 11:24:35

标签: 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已将实际的期限阈值调整为5.现在,对于年龄为n的所有对象,将会发生什么? 5来自 timeStamp1

Haven没有找到任何关于此的文件。

1 个答案:

答案 0 :(得分:0)

我离JDK代码库的专家很远,但我相信你的大部分答案都是我提到的课程。我粗略地从粗略的阅读中猜测,并且非常高兴听到更正。

问题1:

根据http://hg.openjdk.java.net/jdk8/jdk8/hotspot/file/87ee5ee27509/src/share/vm/gc_implementation/shared/ageTable.cpp L81和next(compute_tenuring_threshold),JVM将遍历每个年龄并累加具有该年龄的对象的大小。一旦超过desired_survivor_size,它就会停止并假设它到达的最后年龄作为候选新阈值。选择的新阈值为min(candidateAge,MaxTenuringThreshold)

http://hg.openjdk.java.net/jdk8/jdk8/hotspot/file/87ee5ee27509/src/share/vm/gc_implementation/shared/g1CollectorPolicy.cpp的G1中调用compute_tenuring_threshold,根据ceil(_young_list_target_length / SurvivorRatio)选择_max_survivor_regions,然后调用上面的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);

我没有查看模型,但我想这会回答你的问题:在较低的年龄足以保持desired_survivor_size(这里解释了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&gt;的对象都将被访问。 newAge将终身(包括年龄<时间戳1的阈值但现在超过它的那些)。

我希望这有点道理。