程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 對象清除時的困境:由誰負責清除?

對象清除時的困境:由誰負責清除?

編輯:關於JAVA

每個對象都要求資源才能“生存”,其中最令人注目的資源是內存。如果不再需要使用一個對象,就必須將其清除,以便釋放這些資源,以便其他對象使用。如果要解決的是非常簡單的問題,如何清除對象這個問題並不顯得很突出:我們創建對象,在需要的時候調用它,然後將其清除或者“破壞”。但在另一方面,我們平時遇到的問題往往要比這復雜得多。
舉個例子來說,假設我們要設計一套系統,用它管理一個機場的空中交通(同樣的模型也可能適於管理一個倉庫的貨櫃、或者一套影帶出租系統、或者寵物店的寵物房。這初看似乎十分簡單:構造一個集合用來容納飛機,然後創建一架新飛機,將其置入集合。對進入空中交通管制區的所有飛機都如此處理。至於清除,在一架飛機離開這個區域的時候把它簡單地刪去即可。
但事情並沒有這麼簡單,可能還需要另一套系統來記錄與飛機有關的數據。當然,和控制器的主要功能不同,這些數據的重要性可能一開始並不顯露出來。例如,這條記錄反映的可能是離開機場的所有小飛機的飛行計劃。所以我們得到了由小飛機組成的另一個集合。一旦創建了一個飛機對象,如果它是一架小飛機,那麼也必須把它置入這個集合。然後在系統空閒時期,需對這個集合中的對象進行一些後台處理。
問題現在顯得更復雜了:如何才能知道什麼時間刪除對象呢?用完對象後,系統的其他某些部分可能仍然要發揮作用。同樣的問題也會在其他大量場合出現,而且在程序設計系統中(如C++),在用完一個對象之後必須明確地將其刪除,所以問題會變得異常復雜(注釋⑥)。

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

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

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

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

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

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved