java靜態常量池和運行時常量池


Java虛擬機的靜態常量池和運行時常量池

靜態)常量池:用於存放編譯器生成的各種字面量和符號引用(符號引用區別於直接引用,后者在class字節碼文件被虛擬機解析之后,符號引用將被替換為直接引用)。

運行時常量池:(靜態)常量池中的內容在類加載(這里的類加載指class字節碼文件經過加載連接初始化的過程)后存放入方法區的運行時常量池中。相對於靜態常量池,運行時常量池具有動態性,在程序運行的時候可能將新的常量放入運行時常量池中,比如使用String類的intern方法。

對靜態常量池直觀的理解,它是編譯器編譯java代碼之后所產生的常量,這里的常量跟編寫代碼的常量不同,指的是類、接口、方法和字段的描述信息,比如類的名稱和其基類。“靜態”,是因為它們只是一個class的描述信息而已,還沒有具備被執行的能力。在該class文件被JVM裝載完成之后,靜態常量池中的內容將被解析,並放到運行時常量池中。動態常量池和靜態常量池可以類比程序和進程的關系。

運行時常量池包含:

類、接口、方法和類字段的表述信息
字符串常量池
被final所修飾的類變量
自動包裝類Byte,Short,Integer,Long,Character在-128到127之間值。
方法區:用於存儲已被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯之后的代碼等數據。

按照這樣的理解,因為靜態常量池中的內容只是編譯之后的產物,所以其不保存在方法區中。

這便是(靜態)常量池和動態常量池的區別

Java靜態常量池和運行時常量池

Java中的常量池,實際上分為兩種形態:靜態常量池和運行時常量池。

所謂靜態常量池,即*.class文件中的常量池,class文件中的常量池不僅僅包含字符串(數字)字面量,還包含類、方法的信息,占用class文件絕大部分空間。
而運行時常量池,則是jvm虛擬機在完成類裝載操作后,將class文件中的常量池載入到內存中,並保存在方法區中,我們常說的常量池,就是指方法區中的運行時常量池。
運行時常量池相對於Class文件常量池的另外一個重要特征就是具備動態性,Java語言並不要求常量一定只有在編譯期才能產生,也就是並非預置入Class文件中常量池的內容才能進入方法區運行時常量池,運行期間也可能將新的常量放入池中,這種特性被開發人員利用得比較多的便是String類的intern()方法.其中intern()方法描述如下:

既然運行時常量池是方法區的一部分,自然受到方法區內存的限制,當常量池無法再申請到內存時會拋出OutOfMemoryError異常。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM