文章目录
对象的生死
引用计数算法
给对象中添加一个引用计数器,每当一个地方引用它时,计数器值就加1,当引用失效时,计数器值就减1,当计数器的值为0时,这个对象就是不可能再被使用的。此算法很难解决循环依赖的问题。
可达性分析算法
通过一系列的“GC Roots”的对象作为起点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连,则证明这个对象是不可用的
可作为GC Roots的对象:
- 虚拟机栈(栈帧中的本地变量表)中引用的对象
- 方法区中类静态属性引用的对象
- 方法区中常量引用的对象
- JNI中引用的对象
生存还是死亡
回收方法区
垃圾收集算法
1.标记-清除算法
2.复制算法
3. 标记-整理算法
4.分代收集算法
垃圾收集器
内存分配与回收策略
1.对象优先在Eden分配
当Eden区没有足够空间进行分配时,虚拟机将发起一次Minor GC
2.大对象直接进入老年代
大对象指的是需要大量连续内存的Java对象(很长的字符串及数组)
3.长期存活的对象将进入老年代
虚拟机给每个对象定义了一个对象年龄计数器。如果对象在Eden出生并经过一次Minor GC后仍然存活且能被Survivor容纳的话,将被移进Survivor空间,并将对象年龄设置为1,此后,对象在Survivor区中每熬过一次Minor GC,年龄就增加一岁,当增加到一定年龄后(默认15)将会被晋升到老年代中
此年龄阈值可通过-XX:MaxTenuringThreshold设置
4.动态对象年龄判定
虚拟机并不永远要求对象年龄必须达到MaxTenuringThreshold才会晋升老年代,如果在Survivor空间中相同年龄的所有对象的大小总和大于Survivor空间的一半,那么所有大于或等于此年龄的对象就可以直接进入老年代
5.空间分配担保
在发生Minor GC之前,虚拟机会检查老年代最大可用的连续空间是否大于新生代所有对象总空间,若成立,那么Minor GC可以确保是安全的,否则虚拟机会查看HandlePromotionFailure设置值是否允许担保失败,若允许,会继续检查老年代最大可用的连续空间是否大于历次晋升至老年代对象的平均大小,如果大于,将尝试进行一次Minor GC,尽管这是有风险的,若小于或者HandlePromotionFailure设置为不允许冒险,那么这时改为进行一次Full GC。
在JDK6(Update24)之后规则变为只要老年代最大可用的连续空间大于历次晋升至老年代对象的平均大小就会进行Minor GC,否则进行Full GC。