zoukankan      html  css  js  c++  java
  • JVM误区--动态对象年龄判定

    《深入理解Java虚拟机》中有如上的一段描述,讲的是动态对象年龄判定,避免-XX:MaxTenuringThreshold 设置过大导致大量对象无法晋升。
    但是存在一个问题,如果说非得相同年龄所有对象大小总和大于Survivor空间的一半才能晋升,按照如下场景:
    1. MaxTenuringThreshold为15
    2. 年龄1的对象占用了33%
    3. 年龄2的对象占用33%
    4. 年龄3的对象占用34%。

    得出推论:

    1. 按照晋升的标准。首先年龄不满足MaxTenuringThreshold,不会晋升。
    2. 每个年龄的对象都不满足50%,不会晋升。

    Survivor都占用了100%了,但是对象就不晋升。导致老年代明明有空间,但是对象就停留在年轻代。但这个结论似乎与jvm的表现不符合,只要老年代有空间,最后还会晋升的。

    把晋升年龄计算的代码摘出。我们来看看动态年龄的计算。

    uint ageTable::compute_tenuring_threshold(size_t survivor_capacity) {
        //survivor_capacity是survivor空间的大小
      size_t desired_survivor_size = (size_t)((((double) survivor_capacity)*TargetSurvivorRatio)/100);
      size_t total = 0;
      uint age = 1;
      while (age < table_size) {
        total += sizes[age];//sizes数组是每个年龄段对象大小
        if (total > desired_survivor_size) break;
        age++;
      }
      uint result = age < MaxTenuringThreshold ? age : MaxTenuringThreshold;
        ...
    }

    代码中有一个TargetSurvivorRatio的值。

    # 目标存活率,默认为50%
    -XX:TargetSurvivorRatio

    根据代码可以看到,动态年龄计算方式为:

    1. 通过这个比率来计算一个期望值,desired_survivor_size 。
    2. 然后用一个total计数器,累加每个年龄段对象大小的总和。
    3. 当total大于desired_survivor_size 停止。
    4. 然后用当前age和MaxTenuringThreshold 对比找出最小值作为结果。

    总体表征就是,年龄从小到大进行累加,当加入某个年龄段后,累加和超过survivor区域*TargetSurvivorRatio的时候,就从这个年龄段网上的年龄的对象进行晋升。

    所以上面的场景,年龄1的占用了33%,年龄2的占用了33%,累加和超过默认的TargetSurvivorRatio(50%),年龄2和年龄3的对象都要晋升。

    动态对象年龄判断,主要是被TargetSurvivorRatio这个参数来控制。而且算的是年龄从小到大的累加和,而不是某个年龄段对象的大小。

     
    参考:
    《深入理解Java虚拟机》
  • 相关阅读:
    POJ 1887 Testing the CATCHER
    HDU 3374 String Problem
    HDU 2609 How many
    POJ 1509 Glass Beads
    POJ 1458 Common Subsequence
    POJ 1159 Palindrome
    POJ 1056 IMMEDIATE DECODABILITY
    POJ 3080 Blue Jeans
    POJ 1200 Crazy Search
    软件体系结构的艺术阅读笔记1
  • 原文地址:https://www.cnblogs.com/zjfjava/p/13861797.html
Copyright © 2011-2022 走看看