首頁 >Java >java教程 >JAVA中字串常數池和緩衝池的作用是什麼

JAVA中字串常數池和緩衝池的作用是什麼

王林
王林轉載
2023-05-18 19:22:121196瀏覽

JAVA中字串常數池和緩衝池的作用是什麼


1 常數池

#常數池分成兩個類型,一是.class檔案中靜態的常數池,二是.class檔案中的靜態常數池被載入到JVM中而形成的運行時常數池

1.1 靜態常數池

.class檔案中的常數池可以看作一個數組,數組中儲存了一些常數,當需要在字節碼指令中用到這個常數的時候,就透過陣列的索引來存取它。

看下面的程式碼:

 String m = "hellohellohellohellohello";
 String n = "hellohellohellohellohello";

它在字節碼中將會是這種形式:

 // 常量池:
 #1 hellohellohellohellohello
 #2 ...
 ...
 ----------------------------
 
 String m = #1;
 String n = #1;

當然,這只是一個簡化的版本,實際上要更複雜(實際的版本可以看文章末尾參考資料部分裡面貼出的那個回答,目前可以先只考慮簡化的版本)

注意,在這個裡面存儲的字符串常量只是一個簡單的UTF8編碼的位元組序列,而不是Java的字串對象,它就和你在一個txt文字中儲存的字串一樣,我們用UTF8格式來開啟一個.class文件,可以看到hellohellohellohellohello是可以被解析的:JAVA中字串常數池和緩衝池的作用是什麼

1.2 運行時常數池

理解了靜態的常數池之後,運行時常數池就很容易想明白了。簡單來說,執行時間常數池就是.class檔案中的靜態常數池在JVM中的執行時間表示,每一個.class檔案的靜態常數池都會產生一個對應的執行時間常數池。等到JVM在解釋String m = #1這條指令時,它可以去這個類別的執行時間常數池中找出#1的定義。

2 字串池

字串池是Java為了重複使用String物件而設定的快取池,Java1.7之前設定在方法區上,儲存的是String物件;Java1.7之後設定在堆上,保存的是String物件的引用,String物件本身存在於堆上的其他位置。下文以Java1.7之後的情況為標準。

繼續上面的例子。當JVM在解釋String m = #1時,它已經從運行時常數池拿到了對應的UTF8序列,接下來,它會在字串池中尋找和這個UTF8序列對應的String對象,並把這個對象的引用賦值給m。你可能會好奇這個String被創建的時機,根據R大的這篇文章,在這條語句所在的類別被載入時,如果字串池中已經存在對應的物件了,那麼就什麼都不做,如果不存在,就會建立一個對應的String對象,並把其引用放入池中。

除了字串池,IntegerLong等Wrapper類型也有自己的快取池,例如Integer會快取從-128~127的Integer對象,當使用字面量賦值或Integer.valueOf()時,如果池中存在相應的對象,就會返回池中的對象,只有當池中沒有時才會在堆上建立新物件。

不過,和字串池不同的時,這些Wrapper池不會像字串池一樣可以增長,也就是池中的物件數目是固定的,Integer池中只會有-128~127 。

基本型別對應的緩衝池如下:

boolean values true and false
 all byte values
 short values between -128 and 127
 int values between -128 and 127
 char in the range \u0000 to \u007F

在jdk 1.8 所有的數值類別緩衝池中,Integer 的緩衝池IntegerCache 很特殊,這個緩衝池的下界是- 128,上界預設是127,但這個上界是可調的,在啟動jvm 的時候,透過-XX:AutoBoxCacheMax= 來指定這個緩衝池的大小,該選項在JVM 初始化的時候會設定一個名為java.lang .IntegerCache.high 系統屬性,然後IntegerCache 初始化的時候就會讀取該系統屬性來決定上界。

以上是JAVA中字串常數池和緩衝池的作用是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:yisu.com。如有侵權,請聯絡admin@php.cn刪除