search
尋找貓咪~QQ 地點 桃園市桃園區 Taoyuan , Taoyuan

尚學堂java學習筆記:清除時的困境

由誰負責清除?

每個對象都要求資源才能生存,其中最令人注目的資源是內存。如果不再需要使用一個對象,就必須將其清除,以便釋放這些資源,以便其他對象使用。如果要解決的是非常簡單的問題,如何清除對象這個問題並不顯得很突出:我們創建對象,在需要的時候調用它,然後將其清除或者破壞。但在另一方面,我們平時遇到的問題往往要比這複雜得多。

舉個例子來說,假設我們要設計一套系統,用它管理一個機場的空中交通(同樣的模型也可能適於管理一個倉庫的貨櫃、或者一套影帶出租系統、或者寵物店的寵物房。這初看似乎十分簡單:構造一個集合用來容納飛機,然後創建一架新飛機,將其置入集合。對進入空中交通管制區的所有飛機都如此處理。至於清除,在一架飛機離開這個區域的時候把它簡單地刪去即可。

但事情並沒有這麼簡單,可能還需要另一套系統來記錄與飛機有關的數據。當然,和控制器的主要功能不同,這些數據的重要性可能一開始並不顯露出來。例如,這條記錄反映的可能是離開機場的所有小飛機的飛行計劃。所以我們得到了由小飛機組成的另一個集合。一旦創建了一個飛機對象,如果它是一架小飛機,那麼也必須把它置入這個集合。然後在系統空閑時期,需對這個集合中的對象進行一些後台處理。

問題現在顯得更複雜了:如何才能知道什麼時間刪除對象呢?用完對象后,系統的其他某些部分可能仍然要發揮作用。同樣的問題也會在其他大量場合出現,而且在程序設計系統中(C++),在用完一個對象之後必須明確地將其刪除,所以問題會變得異常複雜(註釋⑥)

⑥:注意這一點只對內存堆里創建的對象成立(new命令創建的)。但在另一方面,對這兒描述的問題以及其他所有常見的編程問題來說,都要求對象在內存堆里創建。

Java中,垃圾收集器在設計時已考慮到了內存的釋放問題(儘管這並不包括清除一個對象涉及到的其他方面)。垃圾收集器知道一個對象在什麼時候不再使用,然後會自動釋放那個對象佔據的內存空間。採用這種方式,另外加上所有對象都從單個根類Object繼承的事實,而且由於我們只能在內存堆中以一種方式創建對象,所以Java的編程要比C++的編程簡單得多。我們只需要作出少量的抉擇,即可克服原先存在的大量障礙。

垃圾收集器對效率及靈活性的影響

既然這是如此好的一種手段,為什麼在C++里沒有得到充分的發揮呢?我們當然要為這種編程的方便性付出一定的代價,代價就是運行期的開銷。正如早先提到的那樣,在C++中,我們可在堆棧中創建對象。在這種情況下,對象會得以自動清除(但不具有在運行期間隨心所欲創建對象的靈活性)。在堆棧中創建對象是為對象分配存儲空間最有效的一種方式,也是釋放那些空間最有效的一種方式。在內存堆(Heap)中創建對象可能要付出昂貴得多的代價。如果總是從同一個基礎類繼承,並使所有函數調用都具有同質多形特徵,那麼也不可避免地需要付出一定的代價。但垃圾收集器是一種特殊的問題,因為我們永遠不能確定它什麼時候啟動或者要花多長的時間。這意味著在Java程序執行期間,存在著一種不連貫的因素。所以在某些特殊的場合,我們必須避免用它——比如在一個程序的執行必須保持穩定、連貫的時候(通常把它們叫作實時程序,儘管並不是所有實時編程問題都要這方面的要求——註釋⑦)

⑦:根據本書一些技術性讀者的反饋,有一個現成的實時Java系統(www.newmonics.com)確實能夠保證垃圾收集器的效能。

C++語言的設計者曾經向C程序員發出請求(而且做得非常成功),不要希望在可以使用C的任何地方,向語言里加入可能對C++的速度或使用造成影響的任何特性。這個目的達到了,但代價就是C++的編程不可避免地複雜起來。JavaC++簡單,但付出的代價是效率以及一定程度的靈活性。但對大多數程序設計問題來說,Java無疑都應是我們的首選。



熱門推薦

本文由 yidianzixun 提供 原文連結

寵物協尋 相信 終究能找到回家的路
寫了7763篇文章,獲得2次喜歡
留言回覆
回覆
精彩推薦