垃圾回收<2>垃圾回收相关算法
一.标记阶段: 引用计数算法
对象存活判断
方法一 : 引用计数算法
循环引用
例子
使用-XX:+printGCDetails 打印GC详情, 进行了GC后,发现对象已经被清除了,证明java没有使用引用计数算法
可以查看堆内存的大小是使用了655k,可以将System.gc()去掉运行一遍,可以明显的发现内存变小了,对象被清除了
小结
二.标记阶段: 可达性分析算法
方法二: 可达性分析(或搜索算法,追踪性垃圾收集)
GC Roots
注意
三.对象的finalization机制
生存还是死亡
具体过程
示例
public class CanReliveObj {
public static CanReliveObj obj;// 类变量,属于GC Root
/**
* 此方法只能被调用一次
* @throws Throwable
*/
@Override
protected void finalize() throws Throwable {
super.finalize();
System.out.println("调用当前类重写的finalize()方法");
obj = this; // 当前待回收的对象在finalize()方法中与引用链上的一个对象obj建立了联系
}
public static void main(String[] args) throws InterruptedException {
obj = new CanReliveObj();
// 对象第一次成功拯救自己
obj = null;
System.gc();// 调用垃圾回收器
System.out.println("第一次 GC");
// 因为Finalizer线程优先级很低,暂停两秒,等待它
Thread.sleep(2000);
if (obj == null) {
System.out.println("obj is dead");
} else {
System.out.println("obj is still alive");
}
System.out.println("第二次 GC");
// 下面这段代码和上面一样,但是这次自救失败了
obj = null;
System.gc();
Thread.sleep(2000);
if (obj == null) {
System.out.println("obj is dead");
} else {
System.out.println("obj is still alive");
}
}
}
第一次注释finalize()方法执行:
第二次重写finalize()方法执行:
四.MAT与JProfiler的GC Roots溯源
获取dump文件
public class GCRootsTest {
public static void main(String[] args) throws InterruptedException {
List<Object> numList = new ArrayList<>();
Date birth = new Date();
for (int i = 0; i < 100; i++) {
numList.add(String.valueOf(i));
Thread.sleep(10);
}
System.out.println("数据添加完毕,请操作: ");
new Scanner(System.in).next();
numList = null;
birth = null;
System.out.println("numList,birth 已置空,请操作: ");
new Scanner(System.in).next();
System.out.println("结束");
}
}
方式1: 命令行使用jmap
jmap -dump:format=b,live,file=test1.bin 14036
方式2: 使用JVisualVM导出
导出方法
成勋启动之后,打开jvusualvm,如图不同时间段导出dump文件
然后使用MAT工具打开
可以看出 numList = null; birth = null;之后,这两个就从GCRoot中被移除了
可以进行溯源,查看具体那个对象在哪儿发生了内存泄漏,查看那个对象一直没有被GC处理
示例
五.清除阶段: 标记-清除(Mark - Sweep)算法
标记-清除(Mark - Sweep) 算法
注: 这里进行标记的是可达对象(非垃圾对象),不是标记的垃圾的,反而是垃圾对象的反面.可达对象
在创建对象的时候,在为对象分配内存空间的时候,如果论空间为不规整的话,这个时候就会进行空闲列表分配
六.清除阶段: 复制(Copying)算法
应用场景
七.清除阶段: 标记-压缩(或标记-整理,Mark - Compact)算法
八.小结
对比三种算法
九.分代收集算法
十.增量收集算法,分区算法
增量收集算法
分区算法
降低延迟的方式之一