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