本文轉載自運行時常量池java
運行時常量池( Runtime Constant Pool)是每個類或接口的常量池( Constant_Pool)的運行時表示形式。git
它包括了若干種不一樣的常量:從編譯期可知的數值字面量到必須運行期解析後才能得到的方法或字段引用。運行時常量池扮演了相似傳統語言中符號表( SymbolTable)的角色,不過它存儲數據範圍比一般意義上的符號表要更爲普遍。接口
每個運行時常量池都分配在 Java 虛擬機的方法區之中,在類和接口被加載到虛擬機後,對應的運行時常量池就被建立出來。內存
以上,是Java虛擬機規範中關於運行時常量池的定義。字符串
根據Java虛擬機規範約定:每個運行時常量池都在Java虛擬機的方法區中分配,在加載類和接口到虛擬機後,就建立對應的運行時常量池。get
在不一樣版本的JDK中,運行時常量池所處的位置也不同。以HotSpot爲例:虛擬機
在JDK 1.7以前,方法區位於堆內存的永久代中,運行時常量池做爲方法區的一部分,也處於永久代中。it
由於使用永久代實現方法區可能致使內存泄露問題,因此,從JDK1.7開始,JVM嘗試解決這一問題,在1.7中,將本來位於永久代中的運行時常量池移動到堆內存中。(永久代在JDK 1.7並無徹底移除,只是原來方法區中的運行時常量池、類的靜態變量等移動到了堆內存中。)io
在JDK 1.8中,完全移除了永久代,方法區經過元空間的方式實現。隨之,運行時常量池也在元空間中實現。編譯
運行時常量池中包含了若干種不一樣的常量:
編譯期可知的字面量和符號引用(來自Class常量池) 運行期解析後可得到的常量(如String的intern方法)
因此,運行時常量池中的內容包含:Class常量池中的常量、字符串常量池中的內容
虛擬機啓動過程當中,會將各個Class文件中的常量池載入到運行時常量池中。
因此, Class常量池只是一個媒介場所。在JVM真的運行時,須要把常量池中的常量加載到內存中,進入到運行時常量池。
字符串常量池能夠理解爲運行時常量池分出來的部分。加載時,對於class的靜態常量池,若是字符串會被裝到字符串常量池中。