Appearance
本章先从什么是短命对象,什么是长命对象引入,分析为什么需要年轻代与老年代,最后总结堆的内部结构是怎样构成的。
什么是短命对象?什么是长命对象?
观察如下代码,分析什么是短命对象?什么是长命对象?
java
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;
}
}
- 长命对象:一直被引用就是长命对象
- 栈一直引用,例如main函数一直运行,它的对象father就一直存活。
- 栈帧出栈后,对象被其他对象引用,例如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>
来调节设置