Java的運行時數據存儲機制



原文地址:http://www.yanwushu.com/post/38.html


Java程序在運行時需要爲一系列的值或者對象分配內存,這些值都存在什麼地方?用什麼樣的數據結構存儲?這些數據結構有什麼特點?本文試圖說明此命題的皮毛之皮毛。


概念


對於Java,有六個不同的、用於數據存儲的概念,他們是:

1.     寄存器( register),是最快的存儲區,位於處理器內部。因爲寄存器的數量極其有限,所以寄存器由編譯器根據需求進行分配。程序員無法使用Java代碼使用寄存器中的存儲空間,或者說:在Java開發的層面上,寄存器的操作已經被封裝。

2.     棧( stack),位於通用 RAM。存取速度快,僅次於寄存器。棧指針若向下移動,則分配新的內存;若向上移動,則釋放那些內存。創建程序時候, JAVA 編譯器必須知道存儲在棧內所有數據的確切大小和生命週期,因爲它必須生成相應的代碼,以便上下移動棧指針,進而分配和釋放內存。由於棧的這種存儲特性,所以某些數據存在棧中,比如對象引用和基礎類型的變量值;但是有些數據是不適合存到棧中的,比如對象的實例。

3.     堆( heap),一個運行時數據區,位於 RAM。堆中的空間是動態分配的,所以,不需要知道數據的大小和生命週期。因此,在堆裏存儲數據有很大的靈活性。Java對象的實例和數組放在這裏。堆中的過期對象由GC負責回收。堆的存取速度較慢。

4.     靜態存儲( static storage),RAM中一片固定的位置。存儲靜態數據,這些數據在程序中用static關鍵字修飾。

5.     常量存儲( constant storage),常量值通常直接存放在程序代碼內部,這樣做是安全的,因爲它們永遠不會被改變。

6.     非 RAM存儲。如果數據完全存活於程序之外,那麼它可以不受程序的任何控制,在程序沒有運行時也可以存在。 


棧和靜態存儲的數據共享


用一個案例理解,假設定義: 

int a = 3; 

int b = 3 ; 

編譯器先處理 int a = 3 ;首先它會在棧中創建一個變量爲a 的引用,然後查找棧中是否有 3 這個值,如果沒找到,就將3 存放進來,然後將 a 指向 3 。接着處理 int b = 3 ;在創建完 b 的引用變量後,因爲在棧中已經有 3 這個值,便將 b 直接指向 3 。這樣,就出現了 a 與 b 同時均指向 3 的情況。這時,如果再令 a=4 ;那麼編譯器會重新搜索棧中是否有 4 值,如果沒有,則將 4 存放進來,並令 a 指向 4 ;如果已經有了,則直接將 a 指向這個地址。因此 a 值的改變不會影響到 b 的值。要注意這種數據的共享與兩個對象的引用同時指向一個對象的這種共享是不同的,因爲這種情況 a 的修改並不會影響到 b, 它是由編譯器完成的,它有利於節省空間。而一個對象引用變量修改了這個對象的內部狀態,會影響到另一個對象引用變量。 

數據共享對於靜態數據同樣。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章