深入核心 Java終止函數詳解
Java終止函數是什么?
對于對象而言,Java 終止函數履行***的確認工作。這與Java 結構函數是相反的,Java 結構函數創建以及初始化了一個Java類實例。當一個對象不在被需要以及這些資源必須被用于其它對象的時候,在一個類實例或者發行的系統資源,比如說文件描述符或者網絡插孔連接上,Java 終止函數可以被用來清除任務。你不需要證據或者為終止函數返回任何值。遺憾的是當一個類或者接口被載入的時候,目前的Java語言的介紹中沒有任何關于終止函數用于Java類或者接口的解釋。讓我們進一步研究一下java.lang對象的終止函數finalize()方法,提供一個方法實例。(如何使用PHP5中的Clone函數)
protected void finalize() throws Throwable
當一個Java對象不再被需要的時候,這個對象原先占有的空間就會期望能夠自動的由Java回收工具進行回收利用。這在Java中有著顯著的差異,并且在大多數的結構性程序語言,比如說C語言中,是不常見的。如果一個類實例實施終止函數finalize()方法,它所占用的空間就不能及時的被回收工具重新回收利用。最壞的情況是也許它根本就不再被回收了。任何實施終止函數finalize() 方法的類實例都經常調用終止對象。當它們不再被引用的時候,它們不能立即被Java回收工具回收,為最終程序Java回收工具將對象附加到指定的隊列。通常是由一個指定的線性程序執行的,在一些Java虛擬機上被稱為“參考句柄”。在最終程序階段,“終止函數”線性程序會執行每一個對象的終止函數finalize()方法。finalize() 成功執行之后Java回收工具將會交付對象,將它所占用的空間由“future”碎片收集功能再生。我沒有說“現有”,這意味著至少兩個碎片收集周期必須被要求用來回收終止對象。聽起來這像是有一些消耗的?正確。我們需要一些方法使得空間能夠重新利用。
線性終止函數在系統中沒有被給予***優先權。優先級更高的線程導致終止對象被排列,如果一個線性“Java終止函數”無法與這個效率保持一致,終止函數隊列就會持續增長,導致Java堆不停的被堆積。最終Java堆將會被耗盡,并且java.lang.OutOfMemoryError將會被扔掉。
對于任何對象而言,一個Java虛擬機將不會超過一次的引用終止函數finalize()方法。如果finalize()方法拋來了什么例外現象,對象的終止程序就會停止下來。
對于類的finalize()方法你幾乎可以自由的做任何事情。當你這樣做的時候,當對象不再被引用或者不再需要的時候,請不要期望存儲空間會被任何一個由Java回收程序回收再生的對象占領。為什么? finalize()方法將要完整的按進度完成的這種情況是不可控的。最壞的情況是,當這里沒有更多涉及到對象的時候,也許它甚至不會被解決。這意味著任何具有finalize()方法的對象被回收都是無法被保障的。這是內存管理發展的一個潛在危險,不必多說,有相當大的開銷是花費在隊列排列、運行finalize()方法以及將對象反射到下一個碎片整理環節上的。
如果你想在對象上運行函數,考慮到終止函數作為***一個方法,執行你自己的清理垃圾方法,這將會更加的平穩。完全信任終止函數來進行事后的垃圾清理工作是非常危險的,特別是當你的終止對象涉及到本地資源的時候。
Java 終止函數的實際操作體驗
ObjectWYieldFinalizer內,我們可以伴隨著線性yield()執行finalize()方法,這樣finalize()就不能完全執行,見代碼表一。線性yield()方法從正在運行的程序中阻止現有的線性程序執行,以及允許其它的線性程序執行。如果終止函數線性程序調用這種finalize()方法,它將會暫停執行。
代碼示例
- /*
- * @Author : Jinwoo Hwang
- * (C) Copyright IBM Corp. 2009. All Rights Reserved
- */
- public class ObjectWYieldFinalizer {
- protected void finalize() throws Throwable {
- Thread.yield();
- }
- }
- public class TestObjectWYieldFinalizer {
- public static void main(String[] args) {
- while(true){
- ObjectWYieldFinalizer o1 = new ObjectWYieldFinalizer();
- }
- }
- }
【編輯推薦】