常量池、運行時常量池、字符串常量池
Java里包含各種常量池,經常傻傻分不清楚,下面就簡單梳理下Java中的池們。
概念解釋
常量池
這里的常量池指的是Class文件常量池。常量池里主要放兩類常量:
- 字面量 :Java語言中定義的常量,如使用final修飾的值
- 符號引用 :表示JVM定義的Java關鍵字或基本類型與實際結構轉換關系
符號引用主要包含以下三種類型:
類和接口的全限定名(Fully Qualified Name)
字段的名稱和描述符(Descriptor)
方法的名稱和描述符
上面說的常量池在JVM中的結構都是一張表。具體有哪些類型的表可以參考下圖
常量池類型表.png
運行時常量池
運行時常量池就是類被JVM加載后在JVM中的版本。有一點兒區別就是常量池只有類文件在編譯的時候才會產生,而且是存儲在類文件中的。而運行時常量池是在方法區,而且可在JVM運行期間動態向運行時常量池中寫入數據。
字符串常量池
字符串常量池是因為Java為String開辟的一塊內存緩沖區,為了提高性能同時減少內存開銷。在JVM中,字符串常量池由一個hash表實現。默認容量為1009。當字符串常量池中的存儲比較多的字符串時,會導致hash沖突,從而每個節點形成長長的鏈表,導致性能下降。所以在使用字符串常量池時,一定要控制容量。
-XX:StringTableSize
通過這個參數可以指定字符串常量池的容量
不同Jdk中字符串常量池的演化
jdk6及以前字符串常量池中存放的是字符串常量
jdk7字符串常量池中存放的是指定字符串的引用
參考
- <<深入理解Java虛擬機: JVM高級特性與最佳實踐>>