JVM–基础–08–内存分配策略–理论
1、介绍
Java虚拟机将堆内存划分为新生代、老年代和永久代
2、新生代(Young)
2.1、介绍
- 新创建的对象在Eden区分配,如果对象是大对象,直接进入老年代。
- 新生代对象朝生夕死,存活率很低,在新生代中,常规应用进行一次垃圾收集一般可以回收70% ~ 95% 的空间,回收效率很高。
- 新生代采用复制算法来回收新生代
- 当Eden区没有足够的空间进行分配时,虚拟机将发起一次Minor GC
2.2、Minor GC触发条件
一旦新创建的对象在eden区放不下的时候,这个时候就触发1次Minor GC。
2.3、新生代中对象的变化
新创建的对象在Eden区分配,如果对象是大对象,直接进入老年代。
随着创建对象的增多,eden区空闲的内存慢慢变少,一旦新创建的对象在eden区放不下的时候,这个时候就触发1次Minor GC。
第1次Minor GC:
1. 通过根可达性算法,获取eden,from区存活的对象,将存活的对象放到to区
1. 如果存活的对象在to去放不下,通过空间担保,将存活的对象放到老年代
第n次Minor GC
1. 通过根可达性算法,获取eden,from区存活的对象,将存活的对象放到to区
1. 如果存活的对象在to去放不下,通过空间担保,将存活的对象放到老年代
2. 如果eden区,from区的对象年龄达到阀值,对象会被移到老年代。
1. 年龄阀值默认为15,新生代中的对象每熬过一轮垃圾回收,年龄值就加1
存活的对象分配到to区后,接着清空Eden区和From区,最后From区和To区交换它们的角色,也就是新的To区就是上次GC清空的From区,新的From区就是上次GC的To区,总之,不管怎样都会保证To区在一轮GC后是空的。
3、老年代(Old)
3.1、介绍
- 在新生代中经历了多次(具体看虚拟机配置的阀值)GC后仍然存活下来的对象会进入老年代中。
- 老年代中的对象生命周期较长,存活率比较高,在老年代中进行GC的频率相对而言较低,而且回收的速度也比较慢。
3.2、对象进入老年代场景
- 大对象直接进入老年代引起
- 由-XX:PretenureSizeThreshold参数定义
- Minor GC时,经历过多次Minor GC仍存在的对象进入老年代。
- 由-XX:MaxTenuringThreashold参数定义
- Minor GC时,动态对象年龄判定机制会将对象提前转移老年代。
- Minor GC时,Eden和From区向To区复制时,To区不够大,会直接把对象转移到老年代。
4、GC
4.1、Minor GC
- 用于清理新生代空间
- 一旦新创建的对象在eden区放不下的时候,这个时候就触发1次Minor GC。
4.2、Full GC 介绍
- 用于清理整个堆空间。包含New、Old。
- Full GC 比Minor GC要慢,因此应该尽可能减少Full GC的次数。
- Full GC 触发条件
- System.gc()被显示调用
- 老年代空间不足,引起Full GC。
- 空间分配担保机制可能会触发Full GC
5、空间分配担保机制
5.1、jdk6版本的空间分配担保
- 空间担保分配是指在发生Minor GC之前
- 只要老年代的连续空间 大于 新生代对象总大小或者历次晋升的平均大小 就会进行Minor GC,否则将进行Full GC。