1.寄存器(register)。這是最快的儲存區,因為它位於不同於其他儲存區的地方——處理器內部。但是寄存器的數量極其有限,所以寄存器由編譯器根據需求進行分配。你不能直接控制,也不能在程式中感覺到寄存器存在的任何跡象。
2. 堆棧(stack)。位於通用RAM(random-access memory,隨機訪問儲存空間)中,但通過它的“堆棧指標”可以從處理器那裡獲得直接支援。堆棧指標若向下移動,則分配新的記憶體;若向上移動,則釋放那些記憶體。這是一種快速有效分配儲存方法,僅次於寄存器。建立程式時,Java 編譯器必須知道儲存在堆棧內所有資料的確切大小和生命週期,因為它必鬚生成相應的代碼,以便上下移動堆棧指標。這一約束限制了程式的靈活性,所以雖然某些Java 資料存放區於堆棧中——特別是對象引用,但是Java 對象並不儲存於其中。
3. 堆(heap)。一種通用性的記憶體池(也存在於RAM 區),用於存放所有的Java 對象。堆不同於堆棧的好處是:編譯器不需要知道要從堆裡分配多少儲存地區,也不必知道儲存的資料在堆裡存活多長時間。因此,在堆裡分配儲存有很大的靈活性。當你需要建立一個對象時,只需用new 寫一行簡單的代碼,當執行這行代碼時,會自動在堆裡進行儲存分配。當然,為這種靈活性必須要付出相應的代價。用堆進行儲存分配比用堆棧進行儲存儲存需要更多的時間(如果確實可以在Java 中像在C++中一樣用棧儲存對象)。
4. 靜態儲存(static storage)。這裡的“靜態”是指“在固定的位置”(儘管也在RAM 裡)。靜態儲存裡存放程式運行時一直存在的資料。你可用關鍵字Static 來標識一個對象的特定元素是靜態,但Java 對象本身從來不會存放在靜態儲存空間裡。
5. 常量儲存(constant storage)。常量值通常直接存放在程式碼內部,這樣做是安全的,因為它們永遠不會被改變。有時,在嵌入式系統中,常量本身會和其它部分隔離開,所以在這種情況下,可以選擇將其存放在ROM(read-only memory,唯讀記憶體)中。
6. 非RAM 儲存(non-RAM storage)。如果資料完全存活於程式之外,那麼它可以不受程式的任何控制,在程式沒有運行時也可以存在。其中兩個基本的例子是“流對象(streamed object)”和“持久化對(persistent object)”。在“流對象”中,對象轉化成位元組流,通常被發送給另一台機器。在“持久化對象”中,對象被存放於磁碟上,因此,即使程式終止,它們仍可以保持自己的狀態。這種儲存方式的技巧在於:把對象轉化成可以存放在其它媒介上的事物,在需要時,可恢複成常規的、基於RAM 的對象
1、Register(寄存器)
存在與CPU中,存取速度最快,但數量有限
2、Stack(棧、堆棧)
存在與記憶體中,存取的速度和效率僅次於Register,在程式載入的時候編譯器必須準確知道所需的所有空間大小,通過指標來操作
3、Heap(堆中)
存在與記憶體中,存取方式靈活,無需編譯器關心,速度比不上Stack
4、Static (靜態類型)
整個程式都可以訪問,對象的屬性可以是靜態,但JAVA對象不會是靜態.
5、Constant(常量)
存在於程式碼中,不能改變
6、非易失性資料
a、流類型資料
b 、持久性資料
就速度來說,有如下關係:
寄存器< 堆棧< 堆< 其他
『上面這段話摘取之《Thinking in Java》』
在這裡,主要要說下堆與堆棧的關係:
堆:堆是heap,是所謂的動態記憶體,其中的記憶體在不需要時可以回收,以分配給新的記憶體請求,其記憶體中的資料是無序的,即先分配的和隨後分配的記憶體並沒有 什麼必然的位置關係,釋放時也可以沒有先後順序。一般由使用者自由分配,malloc分配的就是堆,需要手動釋放。
堆棧:就是STACK。實際上是只有一個出入口的隊列,即後進先出(First In Last Out),先分配的記憶體必定後釋放。一般由,由系統自動分配,存放存放函數的參數值,局部變數等,自動清除。
還有,堆是全域的,堆棧是每個函數進入的時候分一小塊,函數返回的時候就釋放了,靜態和全域變數,new 得到的變數,都放在堆中,局部變數放在堆棧中,所以函數返回,局部變數就全沒了。
其實在實際應用中,堆棧多用來儲存方法的調用。而對則用於對象的儲存。
JAVA中的基本類型,其實需要特殊對待。因為,在JAVA中,通過new建立的Object Storage Service在“堆”中,所以用new 建立一個小的、簡單的變數,如基本類型等,往往不是很有效。因此,在JAVA中,對於這些類型,採用了與C、C++相同的方法。也就是說,不用new 來建立,而是建立一個並非是“引用”的“自動”變數。這個變數擁有它的“值”,共置於堆棧中,因此更高效。