jvm下的棧、堆、方法區和常量池的存儲機制

#說起這些存儲區,對於我們小白來說一定很煩躁。

首先我們先來了解一下他們各自的定義:

#1.棧

- **位於通用RAM中,但通過它的“堆棧指針”可以從處理器哪裏獲得支持。堆棧指針若向下移動,則分配新的內存;若向上移動,則釋放那些 內存。這是一種快速有效的分配存儲方法,僅次於寄存器。創建程序時候,JAVA編譯器必須知道存儲在堆棧內所有數據的確切大小和生命週期,因爲它必鬚生成 相應的代碼,以便上下移動堆棧指針。這一約束限制了程序的靈活性,所以雖然某些JAVA數據存儲在堆棧中——特別是對象引用,但是JAVA對象不存儲其 中。 **

------存放基本類型的變量數據和對象,數組的引用,但對象本身不存放在棧中,而是存放在堆(new 出來的對象)或者常量池中(字符串常量對象存放在常量池中)


#2.堆

- **一種通用性的內存池(也存在於RAM中),用於存放所以的JAVA對象。堆不同於堆棧的好處是:編譯器不需要知道要從堆裏分配多少存儲區 域,也不必知道存儲的數據在堆裏存活多長時間。因此,在堆裏分配存儲有很大的靈活性。當你需要創建一個對象的時候,只需要new寫一行簡單的代碼,當執行 這行代碼時,會自動在堆裏進行存儲分配。當然,爲這種靈活性必須要付出相應的代碼。用堆進行存儲分配比用堆棧進行存儲存儲需要更多的時間。 **

------存放所有new出來的對象。

#3.常量池

- **常量值通常直接存放在程序代碼內部,這樣做是安全的,因爲它們永遠不會被改變。有時,在嵌入式系統中,常量本身會和其他部分分割離開,所以在這種情況下,可以選擇將其放在ROM中 **

------存放字符串常量和基本類型常量(public static final)


例子1 字符串:

String s1 = "china";        
String s2 = "china";        
String s3 = "china";     
String ss1 = new String("china");         
String ss2 = new String("china");         
String ss3 = new String("china");




對於通過 new 產生一個字符串(假設爲 ”china” )時,會先去常量池中查找是否已經有了 ”china” 對象,如果沒有則在常量池中創建一個此字符串對象,然後堆中再創建一個常量池中此 ”china” 對象的拷貝對象。 也就是有道面試題: String s = new String(“xyz”); 產生幾個對象? 一個或兩個。如果常量池中原來沒有 ”xyz”, 就是兩個。如果原來的常量池中存在“xyz”時,就是一個。


例子2 基本數據類型:

 int i1 = 9;        
 int i2 = 9;                 
 public static final int INT1 = 9;                   

-------這裏和字符串的創建和執行相同,就不做說明了。

#4方法區(又叫靜態區)

- **這裏的“靜態”是指“在固定的位置”。靜態存儲裏存放程序運行時一直存在的數據。你可用關鍵字static來標識一個對象的特定元素是靜態的,但JAVA對象本身從來不會存放在靜態存儲空間裏。**

------存放靜態成員(static定義的)

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