//:Garbage.java //Demonstration of the garbage //collector and finalization
class Chair { static boolean gcrun=false; static boolean f=false; static int created=0; static int finalized=0; int i; Chair(){ i=++created; if(created==47) System.out. } protected void finalize(){ if(!gcrun){ gcrun=true; System.out.println( "Beginning to finalize after"+created+ "Chairs have been created"); } if(i==47){ System.out.println( "Finalizing Chair #47,"+ "Setting flag to stop Chair creation"); f=true; } finalized++; if(finalized>=created) System.out.println( "All"+finalized+"finalized"); } }
public class Garbage{ public static void main(String[] args){ if(args.length==0){ System.out.println("Usage:/n"+ "java Garbage before/n or:/n"+ "java Garbage after"); return; } while(!Chair.f){ new Chair(); new String("To take up space"); } System.out.println( "After all chairs have been created:/n"+ "total created ="+Chair.created+ ",total finalized ="+Chair.finalized); if(args[0].equals("before")){ System.out.println("gc():"); System.gc(); System.out.println("runFinalization():"); System.runFinalization(); } System.out.println("bye"); if(args[0].equals("after")) System.runFinalizersOnExit(true); } }///:-
為什么執行java Gerbage before 以后,當所有對象創建完(比如8000個),這時只清除了2000個(不定) 應該只能創建47個對象啊
分析: 首先,在一個循環當中創建對象,并且只是創建,而不引用,也就是說這個對象會自動的被系統當作垃圾處理掉。但請注重,finalize()方法并不是馬上就會執行的,執行的時間完全由系統來決定。所以很有可能的情況是已經創建了20000個對象,才開始其中的某一個對象的清除工作(這可能和時間或者系統內容的占用有關)。看finalize()方法中的一段代碼: if (!gcrun) { gcrun = true; System.out.println( "/nBeginning to finalize after" + created + "Chairs have been created/nat "); } 就會出現這樣的結果: Beginning to finalize after 25038 Chairs have been created
這時對象的創建過程仍在繼續(因為已經Finalize的對象還不滿47個,Chair.f還是false)。所以Chair.created會繼續增加。 直到有47個對象被清除了,Chair.f被置成true了,創建對象的循環才結束。看main方法中的一段代碼: System.out.println( "/nAfter all chairs have been created:/n" + "total created =" + Chair.created + ",total finalized =" + Chair.finalized+"/n"); 如上所說,Chair.created是不斷增加的,而在這段代碼執行之前,又會有N個對象被釋放掉了,所以finalized也增加了。 結果可能是這樣的: total created =29096,total finalized =73
其實這一過程和你使用的JVM有很大關系,執行結果可能會很不相同。但有一點是可以肯定的,那就是我們無法確定JVM什么時候做對象的清除工作(這也是Thinking in java中這段代碼的想要說明的),可能會在這個對象剛剛“無用”的時候就清除掉了,也可能滯后幾秒,甚至永遠不清除。
假如你的開發環境支持跟蹤的話,你可以以STEP的方式運行,你會看到運行結果大不相同。給你看看我的運行結果: Created 47 Beginning to finalize after25038Chairs have been created Finalizing Chair #47,Setting flag to stop Chair creation After all chairs have been created: total created =45993,total finalized =1800 gc(): runFinalization(): bye All45993finalized