2010年9月28日 星期二

Java 物件清除與 finalize() 函式使用

垃圾回收器(garbage collection,簡稱GC)回收不再被使用的物件的記憶體空間
這點是自  C\C++ 以來,高階程式語言很大的改變之一

使用 C\C++ 語言撰寫時,memory leak 是最常發生的嚴重錯誤之一
如果使用完的物件沒有被清除,記憶體空間的資源也無法被釋放
Java的垃圾回收器能回收不再被使用的記憶體空間
但是有些重點必須要注意,垃圾回收器只能回收經由new產生的物件
被占用的特殊記憶體,例如從外部的其他語言獲得的物件,清除方式就不能透過GC進行
針對這類的物件,Java提供了 filanlize() method來因應

class 檔中可以定義 finalize() method
當垃圾回收器要開始釋放被物件占用的記憶體時,會先呼叫 finalize()函式
接著在下一次的垃圾回收動作發生時才會回收該記憶體空間
所以一般常見 finalize() 的定義是在垃圾回收時先執行某些重要的清理工作

有個可能比較容易引起誤會的地方是 finalize() 並不是C++的 destructor
差異點在於C++物件一定會被摧毀,所以destrucor絕對會被喚起
但是Java物件卻不一定會被GC回收
GC的執行條件是記憶體接近用完
假如直到程式執行結束都沒有啟動GC,記憶體空間會在程式終止時一次歸還
GC的執行會給程式帶來額外的負擔,能不執行的話自然是最好
因此 finalize() 並不一定會被呼叫
如果有一定要執行的清除動作,必須自行撰寫函式處理
通常影像處理類的任務比較有這類需求
finalize()真正適合使用的時機就只有要清除 non-Java 的物件

沒有留言:

張貼留言