年轻代与老年代

  • Post author:
  • Post category:其他

一 点睛

1 存储在 JVM 中的 Java 对象可以被划分为两类。

  • 一类是生命周期较短的瞬时对象,这类对象的创建和消亡都非常迅速,它的特点是生命周期短,可及时回收。

  • 一类对象的生命周期非常长(比如一些连接的对象),在某些极端的情况下还能够与JVM的生命周期保持一致。

2 Java 堆区进一步细分的话,可以划分为年轻代(YoungGen)和老年代(oldGen)。

3 年轻代又可以划分为 Eden(圣经中的故事) 空间、Survivor0 空间和 Survivor1 空间(有时也叫做 from 区、to 区)。

下面这个参数开发中一般不会用。

从这张图中,得出如下结论。

Eden:From:to =  8:1:1

新生代:老年代  =  1:2

配置新生代与老年代在堆结构的占比。

  • 默认-XX:NewRatio=2,表示新生代占1,老年代占2,新生代占整个堆的 1/3。

  • 可以修改-XX:NewRatio=4,表示新生代占1,老年代占4,新生代占整个堆的 1/5。

当发现在整个项目中,生命周期长的对象偏多,那么就可以通过调整老年代的大小,来进行调优。

在 HotSpot 中,Eden 空间和另外两个 survivor 空间缺省所占的比例是8:1:1。

开发人员可以通过选项“-XX:SurvivorRatio”调整这个空间比例。比如-XX:SurvivorRatio=8

几乎所有的 Java 对象都是在 Eden 区被 new 出来的。

绝大部分的 Java 对象的销毁都在新生代进行了。(有些大的对象在Eden区无法存储时候,将直接进入老年代)

IBM公司的专门研究表明,新生代中 80% 的对象都是“朝生夕死”的。

可以使用选项”-Xmn”设置新生代最大内存大小。这个参数一般使用默认值就可以了。

上图基本反应了一个对象在堆中的变迁过程。

二 实战

1 代码

/**
* -Xms600m -Xmx600m
* 
* -XX:NewRatio : 设置新生代与老年代的比例。默认值是 2.
* -XX:SurvivorRatio :设置新生代中 Eden 区与 Survivor 区的比例。默认值是 8
* -XX:-UseAdaptiveSizePolicy :关闭自适应的内存分配策略  (暂时用不到)
* -Xmn:设置新生代的空间的大小。 (一般不设置),它的优先级高于 XX:NewRatio
*/
public class EdenSurvivorTest {
    public static void main(String[] args) {
        System.out.println("我只是来打个酱油~");
        try {
            Thread.sleep(1000000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

2 测试1——查看堆中各区的比例情况

E:\javatest1\src\main\java\jvm>jps
12112 Jps
13568
16932 Main
12440 KotlinCompileDaemon
5848 EdenSurvivorTest
5992 Launcher

E:\javatest1\src\main\java\jvm>jinfo -flag SurvivorRatio 5848
-XX:SurvivorRatio=8

E:\javatest1\src\main\java\jvm>jinfo -flag NewRatio 5848
-XX:NewRatio=2 

3 测试2——查看堆中各区的比例情况

4 测试3—— -XX:SurvivorRatio 的测试

从测试2的结果看,Survivor 和 Eden 比例是6,而不是8。这是自适应的内存分配策略参数(-XX:+UseAdaptiveSizePolicy)造成的。

关闭自适应的内存分配策略参数(-XX:-UseAdaptiveSizePolicy)。

发现 Survivor 和 Eden 比例还是6,没有起作用。

只有显示设置 -Xms600m -Xmx600m -XX:SurvivorRatio=8,才起作用。


版权声明:本文为chengqiuming原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。