1. 程式人生 > >JVM 記憶體模型:執行時常量池

JVM 記憶體模型:執行時常量池

1. 前言

最近研究Java基礎知識。發現Java執行時常量池和String字串有些一些細節的地方,值得我們注意的地方,最為一個Java開發人員對於這種java基本特性和JVM虛擬機器的記憶體模型我們需要去深入研究和掌握。

2. 執行時常量池

執行時常量池存在於方法區中,用於存放編譯期生成的各種字面量和符號引用。

2.1 String Pool

String Pool是執行時常量池中虛擬出來的一個概念。

Java中字串物件建立有兩種形式,一種為字面量形式,如String str = “droid”;,另一種就是使用new這種標準的構造物件的方法,如String str = new String(“droid”);,這兩種方式我們在程式碼編寫時都經常使用,尤其是字面量的方式。然而這兩種實現其實存在著一些效能和記憶體佔用的差別。這一切都是源於JVM為了減少字串物件的重複建立,其維護了一個特殊的記憶體,這段記憶體被成為字串常量池或者字串字面量池。

2.1.1 工作原理

當代碼中出現字面量形式建立字串物件時,JVM首先會對這個字面量進行檢查,如果字串常量池中存在相同內容的字串物件的引用,則將這個引用返回,否則新的字串物件被建立,然後將這個引用放入字串常量池,並返回該引用。

2.1.2 字面量建立形式

String str1 = "droid";

JVM檢測這個字面量,這裡我們認為沒有內容為droid的物件存在。JVM通過字串常量池查詢不到內容為droid的字串物件存在,那麼會建立這個字串物件,然後將剛建立的物件的引用放入到字串常量池中,並且將引用返回給變數str1。如果接下來有這樣一段程式碼

String str2 =
"droid";

JVM還是要檢測這個字面量,JVM通過查詢字串常量池,發現內容為”droid”字串物件存在,於是將已經存在的字串物件的引用返回給變數str2。注意這裡不會重新建立新的字串物件。

2.1.3 使用new建立

String str3 = new String("droid");

當我們使用了new來構造字串物件的時候,不管字串常量池中有沒有相同內容的物件的引用,新的字串物件都會建立。因此我們使用下面程式碼測試一下,

String str4 = new String("droid");
System.out.println(str4 == str3);

結果如我們所想,為false,表明這兩個變數指向的為不同的物件。

2.1.4 intern

對於上面使用new建立的字串物件,如果想將這個物件的引用加入到字串常量池,可以使用intern方法。

呼叫intern後,首先檢查字串常量池中是否有該物件的引用,如果存在,則將這個引用返回給變數,否則將引用加入並返回給變數。

String str4 = str3.intern();
System.out.println(str4 == str1);

輸出的結果為true。


對於基礎型別的變數和常量:變數儲存在棧中,常量儲存在常量池中
如以下程式碼:

int i1 = 9; 
int i2 = 9; 
int i3 = 9;  
public static final int INT1 = 9; 
public static final int INT2 = 9; 
public static final int INT3 = 9;