原文地址:http://yanwushu.sinaapp.com/java_data_storage/
Java程序在運行時需要為1系列的值或?qū)ο蠓峙鋬?nèi)存,這些值都存在甚么地方?用甚么樣的數(shù)據(jù)結(jié)構(gòu)存儲?這些數(shù)據(jù)結(jié)構(gòu)有甚么特點?本文試圖說明此命題的皮毛之皮毛。
概念
對Java,有6個不同的、用于數(shù)據(jù)存儲的概念,他們是:
1. 寄存器( register),是最快的存儲區(qū),位于處理器內(nèi)部。由于寄存器的數(shù)量極為有限,所以寄存器由編譯器根據(jù)需求進行分配。http://www.vxbq.cn沒法使用Java代碼使用寄存器中的存儲空間,或說:在Java開發(fā)的層面上,寄存器的操作已被封裝。
2. 棧( stack),位于通用 RAM。存取速度快,僅次于寄存器。棧指針若向下移動,則分配新的內(nèi)存;若向上移動,則釋放那些內(nèi)存。創(chuàng)建程序時候, JAVA 編譯器必須知道存儲在棧內(nèi)所有數(shù)據(jù)的確切大小和生命周期,由于它必須生成相應(yīng)的代碼,以便上下移動棧指針,進而分配和釋放內(nèi)存。由于棧的這類存儲特性,所以某些數(shù)據(jù)存在棧中,比如對象援用和基礎(chǔ)類型的變量值;但是有些數(shù)據(jù)是不合適存到棧中的,比如對象的實例。
3. 堆( heap),1個運行時數(shù)據(jù)區(qū),位于 RAM。堆中的空間是動態(tài)分配的,所以,不需要知道數(shù)據(jù)的大小和生命周期。因此,在堆里存儲數(shù)據(jù)有很大的靈活性。Java對象的實例和數(shù)組放在這里。堆中的過期對象由GC負(fù)責(zé)回收。堆的存取速度較慢。
4. 靜態(tài)存儲( static storage),RAM中1片固定的位置。存儲靜態(tài)數(shù)據(jù),這些數(shù)據(jù)在程序中用static關(guān)鍵字修飾。
5. 常量存儲( constant storage),常量值通常直接寄存在程序代碼內(nèi)部,這樣做是安全的,由于它們永久不會被改變。
6. 非 RAM存儲。如果數(shù)據(jù)完全存活于程序以外,那末它可以不受程序的任何控制,在程序沒有運行時也能夠存在。
棧和靜態(tài)存儲的數(shù)據(jù)同享
用1個案例理解,假定定義:
int a = 3;
int b = 3 ;
編譯器先處理 int a = 3 ;首先它會在棧中創(chuàng)建1個變量為a 的援用,然后查找棧中是不是有 3 這個值,如果沒找到,就將3 寄存進來,然后將 a 指向 3 。接著處理 int b = 3 ;在創(chuàng)建完 b 的援用變量后,由于在棧中已有 3 這個值,便將 b 直接指向 3 。這樣,就出現(xiàn)了 a 與 b 同時均指向 3 的情況。這時候,如果再令 a=4 ;那末編譯器會重新搜索棧中是不是有 4 值,如果沒有,則將 4 寄存進來,并令 a 指向 4 ;如果已有了,則直接將 a 指向這個地址。因此 a 值的改變不會影響到 b 的值。要注意這類數(shù)據(jù)的同享與兩個對象的援用同時指向1個對象的這類同享是不同的,由于這類情況 a 的修改其實不會影響到 b, 它是由編譯器完成的,它有益于節(jié)省空間。而1個對象援用變量修改了這個對象的內(nèi)部狀態(tài),會影響到另外一個對象援用變量。
數(shù)據(jù)同享對靜態(tài)數(shù)據(jù)一樣。