Java對象及元素的歸宿在哪裏

在JAVA平臺上開發應用程序的時候,有一個很大的特點就是其是在應用程序運行的時候才建立對象。換句話說,在程序運行的時候,纔會最終確定對象的歸屬,即對象應該存儲在什麼地方。由於存儲在不同的區 ,其在性能上會有所不同。爲此作爲Java程序開發人員需要了解各個存儲區域的特點以及對性能的影響。然後再根據需要來調整應用程序的區域分配。總的來說,在操作系統 中有五個地方可以用來保存應用程序運行中的數據。這類區域的特點以及對性能的影響分析如下。

  保存區域一:寄存器。

  雖然同在內存中,但是不同的區域由於用途不同,其性能也有所不同。如就拿Java應用程序來說,寄存器由於其處於處理器的內部,爲此這個區域存 取數據最快。跟內存中的其他存儲區域有着天壤之別。那麼我們把所有對象都放到這個區域內,不就可以提高Java應用程序的性能了嗎?理論上是如此,但是在 現實中是行不通的。因爲這個寄存器的數量是非常有限的。在內存中的寄存器區域是由編譯器根據需要來分配的。我們程序開發人員不能夠通過代碼來控制這個寄存 器的分配。所以說,這第一個存儲區域寄存器,我們只能夠看看,而不能夠對其產生任何的影響。

  保存區域二:堆棧。

  對象的創建有兩種方式,一是在應用程序開發的過程中就創建對象;二是在程序運行的過程中要用到對象的時候再來創建對象。前者比後者性能要高,而 後者比前者要靈活。這主要是因爲前者創建對象的時候,就是這個堆棧中創建的。雖然其創建的對象沒有保存在寄存器中,但是通過這個對象的推棧指針可以直接從 處理器哪裏獲得相關的支持。如堆棧指針往上移動的時候,則釋放原有對象佔用的內存;如堆棧指針向下移動時,則爲對象分配新的內存。所以,如果把對象存放在 這個堆棧中,雖然性能沒有像存放在寄存器中那麼理想,但是仍然比存儲在其他地方要好的多。

  由於Java程序是在程序運行過程中才根據需要來創建對象。爲此對象就不能夠保存在這個堆棧中。不過Java應用程序也不能夠白白的浪費這個寶 貴的空間。爲此雖然Java對象本身沒有保存在這個堆棧中(不是不保存而是這裏沒有他的容身之地),但是還是應該把一些可以放的內容放到這個堆棧中,以提 高應用程序的性能。如可以把一些對象引用存放在這個堆棧中。

  另外對於一些基本的數據類型對象,Java程序也往往把他們放置在堆棧中,以提高數據處理的性能。如一些整數型、字符型的數據對象,這些對象有 些共同的特點,如對象比較小、是Java程序提供的標準對象等等。對於這些對象由於每個應用程序基本上都需要用到,而且我們程序開發人員只能夠引用這些對 象,而不能夠對其進行更改。爲此Java程序在處理的時候,往往一開始就創建了對象(即直接在堆棧中創建對象並保存),而不像其他對象一樣,在需要的時候 才創建。只所以在堆棧中創建這些對象,還有一個重要的原因。因爲如果在堆棧中創建對象的話,Java編輯器必須知道存儲在堆棧內所有數據的確切大小和生命 週期。爲了得到這些信息,必須產生相關的代碼來獲得這些信息,以便其操作堆棧指針。普通的對象大小、生命週期等等難以預先獲得,爲此在堆棧中創建普通的對 象,對於Java應用程序來說並不是很合適。相反,這些Java編譯器預定義的對象大小並不會隨着機器硬件架構的變化和用戶需求的變化而變化;而且這些對 象往往從始之終都會存在的,所以也不存在生命週期的問題。所以把這些對象放置在堆棧中是合理的,也是可實現的。如此處理,不僅不會影響到對象的靈活性,而 且還可以提供比較好的性能。

  保存區域三:堆。

  堆雖然跟堆棧一樣,都是隨機訪問存儲器中的區域,但是兩者有很大的不同。因爲在堆中,沒有堆棧指針,爲此也就無法直接從處理器那邊獲得支持。爲 此其性能跟堆棧比起來,就有一定的差距。通常情況下,除上面所說的一些預定義對象之外,其他的對象都是保存在這個堆中的。或者說,利用new關鍵字創建的 對象都是保存在堆中的。保存在堆中其好處也是顯而易見的。如Java編譯器不需要知道從堆裏需要分配多少存儲區域,也不必知道存儲的數據在堆裏會存活多長 時間。所以在堆裏分配存儲有很大的靈活性。當需要對象時,我們可以使用New關鍵字建立一個對象。然後系統會自動給這個對象在堆中分配一個區域讓其作爲歸 宿。不過其最大的不足之處,就是在堆中創建對象與分配存儲區域,要比在堆棧中慢許多。魚與熊掌不能兼得呀。

 存儲區 四:靜態存儲區域與常量存儲區域。

  在Java對象中有一些特殊的元素。如有些元素是比較特別的(如利用關鍵字Static定義的變量)。這些變量對於其他對象來說,可能就是靜態 的。爲了更好的管理這些變量,Java在內存中專門劃分了一個靜態存儲區域來管理這些元素。這裏的靜態存儲區域就是指在固定的位置存放應用程序運行時一直 存在的數據。這裏需要明確的一點就是,Java對象是不保存在這個地方的,而只是把對象中的一些特殊元素放置這裏。由於位置固定,所以下次調用的時候就省 去了查找的麻煩。爲此其對於提供應用程序的性能是有利的。作爲我們程序開發人員來說,在書寫代碼的時候,就需要靈活應用Static這個關鍵字。筆者的意 見是,能用則用;不能用的時候也要想着法兒用。特別是有些元素用不用Static關鍵字時對於程序功能沒有影響,此時我們要理直氣壯的在元素前面加上 Static關鍵字。

  在Java對象中還有一類特殊的元素,我們叫做常量。由於常量的值是穩定不變的,如圓周率。爲此把他們放在代碼的內部是可行的。不過有些時候, 在進行一些嵌入式系統開發的時候,我們往往不這麼做。而是會把常量元素跟代碼分開來保存。如我們會根據情況把常量的值存放在一些只讀存儲器中。這主要是爲 了一些特殊的功能考慮的。如出於版權控制的需要。如在打印機上爲了保護原裝耗材的版權,往往把常量跟代碼分開存放。

  存儲區域五:非RAM存儲。

  有時候,有些程序運行所需要的數據我們還會放置在其他地方。如在一些系統中需要用到流對象,這個對象的數據並沒有保存在上面所談到的任何一個存 儲區域,這個對象直接被轉爲爲字節流,發送到其他的主機上去了。另外有一種叫做持久化的對象,其是被存儲在硬盤中的。這些對象平時在應用程序開發過程中用 到的並不是很多,大家只需要瞭解有這些對象的存在即可。等到需要用到的時候,再去深入研究也不遲。

  從上面的分析中我們可以看到,對象的歸屬我們程序開發人員很難控制。寄存器是編譯器來管理的。而堆與堆棧又基本上受到開發平臺的限制,我們程序 人員也沒有這個能耐來干涉他們。其實我們主要能夠調整與控制的就是第四個存儲區域,即靜態存儲與常量存儲。筆者的建議是,對於非嵌入式程序,能夠利用靜態 存儲來實現的,就儘量採用靜態存儲。而對於常量來說,需要根據需要實現的功能來判斷是否需要把常量存儲在只讀存儲器中。有時候對於版權的保護等等需要用到 這個只讀存儲器。

特價!美國JEEP包相機包數碼包 適合任何品牌等
25.0元
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章