文章目录
一、什么是垃圾
二、为什么需要GC
三、早期垃圾回收
四、Java垃圾回收机制
五、标记阶段:引用计数算法
如果java使用的是引用计数算法,那么此时在堆中的两个对象将无法被回收,造成内存泄漏。但实际上此时在堆中的两个对象会被回收,证明:java使用的不是引用计数算法。
六、标记阶段:可达性分析算法
七、对象的finalization机制
测试Object类中的finalize()方法,即对象的finalization机制
public class CanReliveObj {
private static CanReliveObj obj;//类变量,属于GC Root
@Override
protected void finalize() throws Throwable {
super.finalize();
System.out.println("调用当前类重写的finalize()方法");
obj = this;//当前待回收的对象在finalize方法中与引用链上的一个对象obj建立了联系
}
public static void main(String[] args) {
try {
obj = new CanReliveObj();
//第一次拯救自己
obj = null;
System.gc();
System.out.println("第一次 gc");
//因为线程优先级很低,暂停2秒,等待它
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");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
八、MAT与JProfiler的GC Roots溯源
测试代码:
public class GCRootsTest {
public static void main(String[] args) {
List<Object> munList = new ArrayList<>();
Date birth = new Date();
for(int i = 0; i < 100; i++){
munList.add(String.valueOf(i));
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("数据添加完毕,请操作:");
new Scanner(System.in).next();
munList = null;
birth = null;
System.out.println("numList birth已经置空,请操作");
new Scanner(System.in).next();
System.out.println("结束");
}
}
程序执行过程中,每停止一次导出一个dump文件
九、清除阶段:标记-清除算法
十、清除阶段:复制算法
纠正特别的应该是:如果系统中的垃圾对象很多,复制算法很理想才对,因为复制算法需要复制的存活对象数量并不会太大。
十一、清除阶段:标记-压缩算法
十二、小结
十三、分代收集算法
十四、增量收集算法、分区算法