美文网首页
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吗?

    搜索JVM内存新生代的比例,几乎所有的文章都是s0:s1:eden = 1:1:8,但是如果你真的手动去测试过,就...

  • 常用基础参数SurvivorRatio讲解

    -XX:SurvivorRatio 设置新生代中eden和S0/S1空间的比例默认-XX:SurvivorRati...

  • java内存分配进行JVM调优

    本文基础: 1、已经理解JVM内存结构,对堆内存结构有清晰的认识(Eden,s0,s1,OldGen) 2、理解通...

  • JVM内存分代

    堆分代 1、新生代 Young 新生代由 Eden 与 Survivor Space(S0,S1)构成,大小通过-...

  • 内存分配和回收

    GC主要回收区域:JVM 堆 1、堆的区域划分 新生代、老年代 占用内存比例1:2 新生代 eden、from s...

  • 新生代和老年代

    什么是堆:new出来的的对象都会存放在堆当中堆内存分为两个区:(垃圾回收机制)新生代:Eden,s0,s1老年代:...

  • 路漫漫之-理解java虚拟机

    java 内存垃圾回收机制 1. 堆内存结构 年轻代: (包含eden,s0,s1) 此区域主要是存储新创建或新...

  • GC参数

    堆回顾:eden 新生代,新创建的对象s0,s1 survior存活区,大小完全一样,也可叫from to,是复制...

  • 记一次内存泄漏定位过程

    01 机器内存告警,查看jvm内存及gc情况 老年代占比接近90% S0 S1 E O ...

  • JVM-内存-内存溢出

    jvm内存结构 堆区jvm内存区域young区s0+s1s0和s1在同一时间点,只有一个在使用s0和s1是相等的e...

网友评论

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

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