談笑有鴻儒,往來無白丁

          在恰當的時間、地點以恰當的方式表達給恰當的人...  閱讀的時候請注意分類,佛曰我日里面是談笑文章,其他是各個分類的文章,積極的熱情投入到寫博的隊伍中來,支持blogjava做大做強!向dudu站長致敬>> > 我的微博敬請收聽

          一.誰在做 Garbage Collection ?

          ?????? 一種流行的說法:在 C++ 里,是系統在做垃圾回收;而在 Java 里,是 Java 自身在做。

          C++ 里,釋放內存是手動處理的,要用 delete 運算符來釋放分配的內存。這是流行的說法。確切地說,是應用認為不需要某實體時,就需用 delete 告訴系統,可以回收這塊空間了。這個要求,對編碼者來說,是件很麻煩、很難做到的事。隨便上哪個 BBS ,在 C/C++ 版塊里總是有一大堆關于內存泄漏的話題。

          Java 采用一種不同的,很方便的方法: Garbage Collection 。垃圾回收機制放在 JVM 里。 JVM 完全負責垃圾回收事宜,應用只在需要時申請空間,而在拋棄對象時不必關心空間回收問題。

          二.對象在啥時被丟棄?

          ?????? C++ 里,當對象離開其作用域時,該對象即被應用拋棄。

          是對象的生命期不再與其作用域有關,而僅僅與引用有關。

          ?????? Java 的垃圾回收機制一般包含近十種算法。對這些算法中的多數,我們不必予以關心。只有其中最簡單的一個:引用計數法,與編碼有關。

          ?????? 一個對象,可以有一個或多個引用變量指向它。當一個對象不再有任何一個引用變量指向它時,這個對象就被應用拋棄了。或者說,這個對象可以被垃圾回收機制回收了。

          這就是說,當不存在對某對象的任何引用時,就意味著,應用告訴 JVM :我不要這個對象,你可以回收了。

          JVM 的垃圾回收機制對堆空間做實時檢測。當發現某對象的引用計數為 0 時,就將該對象列入待回收列表中。但是,并不是馬上予以銷毀。

          三.丟棄就被回收?

          該對象被認定為沒有存在的必要了,那么它所占用的內存就可以被釋放。被回收的內存可以用于后續的再分配。

          但是,并不是對象被拋棄后當即被回收的。 JVM 進程做空間回收有較大的系統開銷。如果每當某應用進程丟棄一個對象,就立即回收它的空間,勢必會使整個系統的運轉效率非常低下。

          前面說過, JVM 的垃圾回收機制有多個算法。除了引用計數法是用來判斷對象是否已被拋棄外,其它算法是用來確定何時及如何做回收。 JVM 的垃圾回收機制要在時間和空間之間做個平衡。

          因此,為了提高系統效率,垃圾回收器通常只在滿足兩個條件時才運行:即有對象要回收且系統需要回收。切記垃圾回收要占用時間,因此, Java 運行時系統只在需要的時候才使用它。因此你無法知道垃圾回收發生的精確時間。

          四.沒有引用變量指向的對象有用嗎?

          ?????? 前面說了,沒掛上引用變量的對象是被應用丟棄的,這意味著,它在堆空間里是個垃圾,隨時可能被 JVM 回收。

          不過,這里有個不是例外的例外。對于一次性使用的對象(有些書稱之為臨時對象),可以不用引用變量指向它。舉個最簡單也最常見的例子:

          System.out.println(“I am Java!”);

          就是創建了一個字符串對象后,直接傳遞給 println() 方法。

          五.應用能干預垃圾回收嗎?

          ?????? 許多人對 Java 的垃圾回收不放心,希望在應用代碼里控制 JVM 的垃圾回收運作。這是不可能的事。對垃圾回收機制來說,應用只有兩個途徑發消息給 JVM 。第一個前面已經說了,就是將指向某對象的所有引用變量全部移走。這就相當于向 JVM 發了一個消息:這個對象不要了。第二個是調用庫方法 System.gc() ,多數書里說調用它讓 Java 做垃圾回收。

          ?????? 第一個是一個告知,而調用 System.gc() 也僅僅是一個請求。 JVM 接受這個消息后,并不是立即做垃圾回收,而只是對幾個垃圾回收算法做了加權,使垃圾回收操作容易發生,或提早發生,或回收較多而已。

          ?????? 希望 JVM 及時回收垃圾,是一種需求。其實,還有相反的一種需要:在某段時間內最好不要回收垃圾。要求運行速度最快的實時系統,特別是嵌入式系統,往往希望如此。

          ?????? Java 的垃圾回收機制是為所有 Java 應用進程服務的,而不是為某個特定的進程服務的。因此,任何一個進程都不能命令垃圾回收機制做什么、怎么做或做多少。

          六.對象被回收時要做的事

          一個對象在運行時,可能會有一些東西與其關連。因此,當對象即將被銷毀時,有時需要做一些善后工作。可以把這些操作寫在 finalize() 方法(常稱之為終止器)里。

          protected void finalize()

          {

          ? // finalization code here

          }

          這個終止器的用途類似于 C++ 里的析構函數,而且都是自動調用的。但是,兩者的調用時機不一樣,使兩者的表現行為有重大區別。 C++ 的析構函數總是當對象離開作用域時被調用。這就是說, C++ 析構函數的調用時機是確定的,且是可被應用判知的。但是, Java 終止器卻是在對象被銷毀時。由上所知,被丟棄的對象何時被銷毀,應用是無法獲知的。而且,對于大多數場合,被丟棄對象在應用終止后仍未銷毀。

          在編碼時,考慮到這一點。譬如,某對象在運作時打開了某個文件,在對象被丟棄時不關閉它,而是把文件關閉語句寫在終止器里。這樣做對文件操作會造成問題。如果文件是獨占打開的,則其它對象將無法訪問這個文件。如果文件是共享打開的,則另一訪問該文件的對象直至應用終結仍不能讀到被丟棄對象寫入該文件的新內容。

          至少對于文件操作,編碼者應認清 Java 終止器與 C++ 析構函數之間的差異。

          那么,當應用終止,會不會執行應用中的所有 finalize() 呢?據 Bruce Eckel Thinking in Java 里的觀點:“到程序結束的時候,并非所有收尾模塊都會得到調用”。這還僅僅是指應用正常終止的場合,非正常終止呢?

          因此,哪些收尾操作可以放在 finalize() 里,是需要酌酎的。?

          來源:http://dev.csdn.net/author/beepbug/cfda04d9dd5a4409a433f793135e1b8b.html
          posted on 2006-10-08 16:00 壞男孩 閱讀(378) 評論(0)  編輯  收藏 所屬分類: java命令學習
          主站蜘蛛池模板: 本溪市| 莱州市| 泸水县| 克什克腾旗| 甘德县| 利川市| 呼和浩特市| 小金县| 易门县| 金坛市| 略阳县| 辛集市| 喀什市| 三都| 磴口县| 曲麻莱县| 璧山县| 湖南省| 海宁市| 富锦市| 磴口县| 米林县| 治县。| 密云县| 丰都县| 昌平区| 大田县| 水城县| 抚顺市| 昆明市| 西乌珠穆沁旗| 朝阳县| 宁陵县| 黎平县| 深泽县| 定州市| 西乌珠穆沁旗| 湖北省| 绥江县| 呈贡县| 仁寿县|