美文网首页
JVM内存新生代的比例s0:s1:eden = 1:1:8吗?

JVM内存新生代的比例s0:s1:eden = 1:1:8吗?

作者: 憩在河岸上的鱼丶 | 来源:发表于2020-01-30 20:51 被阅读0次

    搜索JVM内存新生代的比例,几乎所有的文章都是s0:s1:eden = 1:1:8,但是如果你真的手动去测试过,就会发现事实并非如此。

    准备工作

    为了验证该问题,首先来一段测试代码,向list集合中添加对象,模拟内存溢出。

    import java.util.ArrayList;
    import java.util.List;
    
    public class Testa {
        public static void main(String[] args) throws InterruptedException {
            List list = new ArrayList<>();
            while(true) {
                list.add(new Object());
                Thread.sleep(100);  // 避免内存过快溢出
            }
        }
    }
    

    然后启动代码,通过 JvisualVM 可以清晰的看到新生代内存比例Survivor0 =Survivor1=435.5M,Eden = 1.328G,比例明显不等于1:1:8

    关闭内存分配策略自适应

    查询资料后得知,JVM有一个关于survivoreden区大小自动变化的一个参数设置-XX:-UseAdaptiveSizePolicy,是默认开启的,关掉就是严格的1:8了。

    于是使用相关命令查看jvm参数,果不其然,该参数是开启的。

    C:\Users\mao>jps
    1412 Testa
    1588 RemoteMavenServer
    5732
    8100 Launcher
    11800 Jps
    6044 Main
    
    // 该命令作用是输出18452进程的UseAdaptiveSizePolicy参数
    // +UseAdaptiveSizePolicy中的+表示已启用
    C:\Users\mao>jinfo -flag UseAdaptiveSizePolicy 18452
    -XX:+UseAdaptiveSizePolicy
    
    

    接下来在代码的启动参数中加上-XX:-UseAdaptiveSizePolicy,表示关闭内存分配策略自适应,然后启动代码。IDEA在Run - Edit Configurations - VM options中添加启动参数。

    然后惊奇的Eden/Survivor=1020M÷170M=6,所以s0:s1:eden仍不是1:1:8,而是s0:s1:eden=1:1:6

    显式设置内存比例

    又从《深入理解JVM》p92中得知,可以使用-XX:SurvivorRatio=8设置新生代中一个Survivor区与Eden区的的比例是1:8,于是使用jinfo查看jvm参数,得知默认值即为8。

    C:\Users\mao>jinfo -flag SurvivorRatio 17588
    -XX:SurvivorRatio=8 
    

    至此,我已大概确信s0:s1:eden=1:1:6了,但是我又做了一次尝试,在代码的启动jvm参数中添加了-XX:-UseAdaptiveSizePolicy -XX:SurvivorRatio=8。然后查看新生代内存比例如下图,Eden/Survivor=1.063*1024M÷170M=8,终于得到了s0:s1:eden=1:1:8的结果。

    总结

    JVM内存的新生代比例s0:s1:eden=1:1:8有两个前提条件:

    1. 关闭内存分配策略自适应(默认开启),-XX:-UseAdaptiveSizePolicy
    2. 手动设置Eden区与Survivor区比例,-XX:SurvivorRatio=8

    问题

    为什么默认设置的-XX:SurvivorRatio=8并不生效,需要手动开启?

    我查看了OpenJDK的源码,并没有找到原因,希望有大神不吝赐教。

    JVM内存的新生代比例问题,困惑了我一年之久,期间问过几次大神,都没有得到答案,感谢图灵学院-诸葛老师的帮助,大致解决了该问题,希望后面的时间里,能解决剩下的这个小问题。

    相关文章

      网友评论

          本文标题:JVM内存新生代的比例s0:s1:eden = 1:1:8吗?

          本文链接:https://www.haomeiwen.com/subject/hwpxyctx.html