GC与垃圾回收分代
gc与finalize
网上很多博客简略的说确保对象死活需要经过两次标记这是错误的。
Object有个finalize,默认是空实现
被回收时会判断这个对象是否重写了finalize方法,如果没有就直接回收
否则会把该对象加入一个f队列(代表需要执行回收方法的队列)
jvm会分配一个执行finalize的线程去执行这个队列每个对象的finalize方法,如果在finalize方法中对象吧自己的this给不在finalize队列中的对象引用,则将其从finalize队列移除
jvm并不保证执行finalize的线程绝对会执行结束,而是超过一个固定时间以后就终止(防止死锁)。
finalize线程终止后,其中还保留的对象都会被回收
判断对象是否存活
以前采用过标记法,即每个对象加一个计数器,被引用了+1,取消引用-1.当为0代表可以回收
此种方法会导致无法处理循环引用(A引用B,B引用A且而GCroot没有任何对象引用A和B,则A和B永远不会被回收),因此被遗弃了
现在普遍使用GCroot扫描方法
GCRoot
以下对象可以作为GCroot
Class - 由系统类加载器(system class loader)加载的对象,这些类是不能够被回收的,他们可以以静态字段的方式保存持有其它对象。
//其他类加载器加载的对象,jvm默认不回收,除非进行特殊指定
Thread - 活着的线程
Stack Local - Java方法栈的local变量或参数
JNI Local - JN