Java的finalize
经常背八股文的我们都知道,面试官常常会问final,finally和finalize的区别。(初级常问,中高级不知道,我不是)
然后finalize一直背得支支吾吾,Object方法,垃圾回收会被调用,不保证什么时候调用。当然认真看看文章会知道是什么回事,但总有一些不喜欢看的,就按着文案背,稀里糊涂。
其实就是上面的三点,Object方法,垃圾回收的时候会先调用,而不是我们调用finalize之后就进行垃圾回收。贴一段代码就知道了
public class Test01 {
public static void main(String[] args) {
int i = 1;
while(true) {
List<TestHHH> list = new ArrayList<>(10000);
TestHHH testHHH = new TestHHH();
list.add(testHHH);
i++;
if (i%100==0){
System.out.println("执行了:"+i+"次");
if (i==10000){
return;
}
}
}
}
}
class TestHHH{
protected void finalize(){
System.out.println("要被清理啦~");
}
}
重写TestHHH的finalize方法,然后创建大内存对象,尽快GC,然后就能看到finalize被调用了。
所以finalize不是我们调用的,是系统自己调用的,在垃圾回收前会调用finalize方法,那finalize方法有什么用呢,既然是垃圾回收的时候调用的,那就是应该做一些该对象回收前该做的事,网上说比如连接池的回收啦,文件流的关闭啦等等。是不是和finally中做的事差不多?是的!
所以Java明确表示不建议使用,将其标志为过期方法。
它本身就是为了方便资源的回收的,但是,它有个很大的问题,就是不确定垃圾回收什么时候进行。垃圾回收机制的回收时机不确定,有一些垃圾回收器会在新生区/老年区内存告急时才进行垃圾回收,那如果一直不进行垃圾回收,那应该在finalize中回收的资源就会一直占用内存,这对程序的性能肯定有影响,但理论上不会导致内存溢出。
所以建议如果要回收的资源,尽量在finally中进行回收。也就是用finally替代finalize。