Java中垃圾确定的方法是:
根可达算法
GC Root 对象:
虚拟机栈中引用的对象
方法区中的常量对象
方法区中类静态属性引用的对象
本地方法栈中JNI的引用对象
活跃线程的引用对象
垃圾回收算法:
1、标记清除 (Mark and Sweep)
标记: 从根引用扫描,对存活的对象进行标记
清除: 对堆内存从头到尾进行线性遍历,回收不可达对象内存
缺点: 碎片化
2、 复制算法( 适用于年轻代,因为年轻代的对象绝大多数都是临时对象)
针对已分配对象内存和空闲内存
对象在对象内存区域分配
回收时将对象内存区存活的对象复制到空闲内存
将对象内存区的所有对象进行清除
2.1、解决碎片化问题
2.2、顺序分配内存、简单高效
2.3 适用对象存活率低的场景
2.4 内存利用不高
3、 标记整理 (适用于老年代)
标记: 从根引用扫描,对存活的对象进行标记
整理: 移动所有存活的对象,按照对象的内存的地址依次排列,然后将末端以后的内存地址全部回收
3.1 避免了内存不连续性(碎片化)
3.2 不设置两块内存互换
3.3 适用于存活率高的场景
4、 分代收集算法
按照对象声明周期的不同划分区域以采用不同垃圾回收算法
目的: 提高JVM的回收率
GC分两类
Minor GC 发生在年轻代 复制算法
Full GC 与老年代相关 标记整理算法 触发Full GC 老年代空间不足、元空间不足、System.gc()
young 区的垃圾对象收集: 当eden区满了,触发Minor GC 存活的拷贝到from区,年龄+1,再次满了eden存活的和from中存活复制到to区,年龄+1,当年龄达到15时复制到养老区。
5、对象如何晋升到老年代?
5.1、经历一定次数Minor GC 依然成活的对象
5.2、survivor区存放不下的对象
5.3、新生成的大对象