天天看點

JVM——運作時常量池

“運作時常量池”  不等于 “常量池”。

運作時常量池 不是 class位元組碼中的常量池,運作時常量池是jvm在運作時,屬于jvm記憶體區域中的一塊記憶體,将class位元組碼檔案中的常量池進行解析,然後再運作時常量池中進行相應的初步記憶體配置設定。

jvm如何執行一個代碼?

加載位元組碼。java代碼是由一個個類組成的,經過編譯後,就形成了一個個class位元組碼檔案,檔案自然是存放在磁盤中的,要執行代碼,就要先啟動java虛拟機(jvm),jvm啟動好了之後,從磁盤中将class位元組碼檔案加載到記憶體中,具體加載到記憶體的哪個區域?jdk1.6版本以前,是加載到方法區(屬于堆區),jdk1.8版本開始,是加載中繼資料區,中繼資料區不屬于jvm運作時的記憶體區,已經獨立出來了。jvm運作時的記憶體大小是有上限的(上限不是整個記憶體大小,是小于整個記憶體的),以前的方法區是jvm記憶體區的一部分,是以方法區就有限,是以class位元組碼(可以了解為程式)太大的話,方法區是容不下的(跑不起來),現在好了,存放在獨立的中繼資料區了,這個中繼資料區大小是可以動态變化的,結合計算機的虛拟存儲技術(記憶體+磁盤),理論上,中繼資料區可以擴充到 部分記憶體+磁盤空間  大小,就基本不用擔心程式太大的問題了(除非記憶體+磁盤都不行)。

JVM——運作時常量池

動态解析位元組碼。jvm解析位元組碼的内容,根據這些内容,在jvm記憶體區域中的相應區域配置設定空間、初始化資料等等。

執行程式。根據程式的代碼,擷取指令、擷取資料、執行指令、處理結果等等。

java語言中一切皆是對象,這個思想在jvm中也一樣,都當做對象來看,為對象配置設定記憶體空間,然後直接使用的是這些對象的引用(類似指針),每一個class檔案的常量池被封裝為一個對象,解析到運作時常量池。

如何根據一個java類的class位元組碼檔案,動态的将其常量池的資訊動态配置設定或者初始化到運作時常量池中,一個類就有一個class位元組碼檔案,就有一個常量池,是以運作時常量池其實是主要存放所有類的位元組碼檔案中的常量池資訊的(不是複制,而是根據常量池資訊動态解析為運作時常量池中的内容)。

class檔案的内容順序是固定的,但是内容大小是不定的,常量池大小也是不定的,jvm是動态解析常量池的内容的,是以會動态配置設定運作時常量池的大小。