年轻代与老年代

2023-07-25 jvm

本章先从什么是短命对象,什么是长命对象引入,分析为什么需要年轻代与老年代,最后总结堆的内部结构是怎样构成的。

# 什么是短命对象?什么是长命对象?

观察如下代码,分析什么是短命对象?什么是长命对象?

public class Father {
    
    private List<Son> sons = new ArrayList<>();
    public Son giveSon(String name) {
        return new Son(name);
    }
    
    public static void main(String[] args) {
        Father father = new Father();
        Son a = father.giveSon("a");
        father.sons.add(a);
        father.giveSon("b");
    }
}
class Son {
    private String nme;
    public Son(String name) {
        this.name = name;
    }
}
  • 长命对象:一直被引用就是长命对象
    1. 栈一直引用,例如main函数一直运行,它的对象father就一直存活。
    2. 栈帧出栈后,对象被其他对象引用,例如giveSon("a"),出栈后被sons引用。
  • 短命对象:没人引用就是短命对象,也称为垃圾对象,因为没人用它,即没人引用它。例如giveSon("b")出栈后里面的son没人引用,就变成垃圾了。
  • 在JVM中,大部分都是短命对象;少数对象长期存活,例如main函数的栈一直引用father, father的sons直应用a

长命对象与短命对象

# 年轻代与老年代

# 什么是分代模型?

分代模型:把堆分为年轻代老年代;年轻代存储短命对象;老年代存储长命对象。

# 为什么要这么设计?设计分代模型?

设计来源于生活,例如生活垃圾放在垃圾桶(年轻代),因为生活垃圾对你没用,所以拿个垃圾桶存起来;砖石黄金存放到保险柜(老年代) ,因为砖石黄金对太多人有用了,所以拿个保险柜保存起来。

如果不设计分代,那么砖石黄金和生活垃圾就放在一起了,会造成管理混乱。

# 堆的内部结构

年轻代和老年代的内存占比是1:2,年轻代还被划分如图所示的两个区域(Eden和Surivior)

堆内存分配

java的堆是按照垃圾收集器来设计的,目前主流的垃圾收集器G1;分代设计的垃圾收集器主要是CMS, G1。

堆的分代设计,就是把一块内存划分为多块;堆的内存空间分配主要是分为2块,年轻代和老年代。

年轻代和老年代的比例是1:2 ,可采用-XX:NewRatio= <n>来调节设置;年轻代分为Eden和Survivor From、Survivor To的大小比例是8: 1: 1可采用-XX:SurvivorRatio= <n>来调节设置

上次更新: 5 个月前