我們都知道,Java的內(nèi)存清理是通過垃圾回收器進(jìn)行的,那么其是如何將沒用的對象被被清理掉的呢。
其實(shí)當(dāng)垃圾回收器準(zhǔn)備回收對象內(nèi)存的時(shí)候,首先會調(diào)用對象的finalize()方法,并且在下一次垃圾回收動作發(fā)生的時(shí)候真正回收對象的內(nèi)存,所以在finalize()中你可以會一些必要的清理工作
那么問題又來了,finalize()是個(gè)什么鬼呀,既然會調(diào)用對象的這個(gè)方法就說明所有的類都會有這個(gè)方法(畢竟所有的類都會被回收嘛),自然而然我們就想到了java的根類 Object.進(jìn)去看看
protected void finalize() throws Throwable { }
最后一行還真找到了,是一個(gè)實(shí)現(xiàn)為空的方法,既然是protected就說明具體的方法可以留給子類去實(shí)現(xiàn)
- 之前我們說過只有當(dāng)對象不再被任何引用指向時(shí)候,該對象才會被回收。那么真的是這樣嗎?我們舉個(gè)栗子看看
public class User {
private int money;
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
public void cool(){
String str=new String();
}
@Override
protected void finalize() throws Throwable {
// TODO Auto-generated method stub
if(money>0){
System.out.println("error");
}
else{
System.out.println("suceess");
}
super.finalize();
}
}
這里我們重寫finalize()方法,在銷毀前如果一個(gè)人的前還沒花光,打印這個(gè)人是失敗的,否則這個(gè)人是成功的。
我們在main()中的代碼
public class Test {
public static void main(String args[]){
User u1=new User(200);
new Object();
new User(100);
}
}
運(yùn)行一下,結(jié)果如下:
居然什么都沒有!運(yùn)行結(jié)束之后不光有引用指向的u1,就連沒有任何引用指向的new User(100);居然都沒有被回收。這是怎么回事呢?
- 我們來看看Thinking In Java中是怎樣解釋的
java中的并非總是被垃圾回收,也就是說對象可能不被回收。一般程序只要不到瀕臨存儲空間用光,垃圾回收器一般都不會主動回收內(nèi)存,如果程序結(jié)束,并且垃圾回收器一直沒有釋放你創(chuàng)建的空間,則隨著程序的退出,資源則會被歸還給操作系統(tǒng)。所以上面的我們finalize()才一直沒有被調(diào)用
- 如果我們想看到效果,可以通過如下方法:
public class Test {
public static void main(String args[]){
User u1=new User(200);
new Object();
new User(100);
System.gc();
}
}
System.gc();會強(qiáng)制系統(tǒng)垃圾回收器工作,運(yùn)行效果如下
error
可以看到new User(100);創(chuàng)建的對象被回收了。
- 至于java的垃圾回收器的具體工作原理,它是如何清理那么已經(jīng)無法被使用的內(nèi)存?這里面涉及的東西就很多了,方法也有很多,等我看明白了再詳細(xì)講解。