深入淺出JVM常量池

常量池在JVM中分為三種:字符串常量池费薄,運(yùn)行時(shí)常量池后德,Class常量池
討論范圍 JDK 1.7版本及以后

字符串常量池(String pool)
(1)什么是字符串常量池部宿?
①字符串常量由一個(gè)個(gè)字符組成。在HotSpot虛擬機(jī)中,字符串常量池是有一個(gè)名為 StringTable 的類來實(shí)現(xiàn)的理张,StringTable是一個(gè)哈希表HashSet<String>赫蛇,默認(rèn)長(zhǎng)度為1009,是被所有類共享的雾叭,因此在JVM中的實(shí)例只有一份悟耘。注意它只存儲(chǔ)對(duì)java.lang.String實(shí)例的引用,而不存儲(chǔ)String對(duì)象的內(nèi)容织狐,根據(jù)這個(gè)引用可以得到具體的String對(duì)象暂幼。一般我們說一個(gè)字符串進(jìn)入了全局的字符串常量池其實(shí)是說在這個(gè)StringTable中保存了對(duì)它的引用,反之移迫,如果說沒有在其中就是說StringTable中沒有對(duì)它的引用旺嬉。

②在JDK1.6版本中,StringTable的長(zhǎng)度是固定的厨埋,長(zhǎng)度就是1009邪媳。因此如果保存的字符串常量過多,就會(huì)造成哈希沖突荡陷,導(dǎo)致鏈表過長(zhǎng)雨效,而鏈表過長(zhǎng)的直接影響就是 當(dāng)調(diào)用String.intern時(shí)性能會(huì)大幅下降(因?yàn)橐粋€(gè)一個(gè)找)。

③在JDK1.7版本中废赞,StringTable的長(zhǎng)度可以通過參數(shù)來指定:-XX:StringTableSize=123456

(2)字符串常量池保存在JVM哪個(gè)區(qū)域徽龟?
在JDK1.6及之前的版本中,字符串常量池是放在永久代(Perm Gen)中唉地,確切來講是永久代的方法區(qū)中顿肺。
在JDK1.7后的版本中,字符串常量池就被移到了堆(Heap)中渣蜗。之所以會(huì)被移到堆中,可能是方法區(qū)的內(nèi)存空間太小了旷祸。

(3)字符串常量池中保存的是什么耕拷?
字符串常量池只存儲(chǔ)引用,不存儲(chǔ)內(nèi)容托享!字符串不是存在字符串常量池中而是存在堆內(nèi)存中骚烧,字符串池中只是該字符串的引用。
規(guī)范里把存儲(chǔ)Java對(duì)象的地方定義為Java heap闰围,其它地方是不會(huì)存有Java對(duì)象的實(shí)體的(有的話那根據(jù)定于也要算Java heap的一部分)

注:在字符串常量池中的字符串只能存在一份赃绊。

String s1 ="JVM";
String s2 ="JVM";
//執(zhí)行完第一段代碼后,由于常量池中已經(jīng)存在了"JVM"這個(gè)字符串的引用羡榴,
//所以s2不會(huì)在常量池中申請(qǐng)新的空間碧查,而是直接把已存在的字符串內(nèi)存地址返回給s2。

Class常量池
(1)什么是Class常量池?
①在每一個(gè)Java類被編譯后忠售,會(huì)形成一個(gè)class文件传惠。Class文件除了有類信息,字段稻扬,方法卦方,接口等描述信息,還有一項(xiàng)信息是常量池(Constant Pool Table)泰佳,每一個(gè)class文件都有一個(gè)class常量池盼砍。

(2)Class常量池保存在JVM哪個(gè)區(qū)域?
保存在堆中逝她。

(3)Class常量池中保存的是什么浇坐?
用于存放編譯器生成的各種字面量(Literal)和符號(hào)引用(Symbolic References);
字面量(Literal)包括:文本字符串汽绢,八種基本類型的值吗跋,被聲明為final的常量等
符號(hào)引用(Symbolic References)包括:類和接口的全限定名(Full Qualified Name),字段的名稱和描述符(Descriptor)宁昭,方法的名稱和描述符

運(yùn)行時(shí)常量池(Runtime Constant Pool)
(1)什么是運(yùn)行時(shí)常量池跌宛?
運(yùn)行時(shí)常量池,則是jvm虛擬機(jī)在完成類裝載操作后积仗,將class文件中的常量池載入到內(nèi)存中疆拘,并保存在方法區(qū)中。 運(yùn)行時(shí)常量池也就是class常量池被加載到內(nèi)存之后的版本寂曹,因?yàn)槊恳粋€(gè)class文件都有一個(gè)class常量池哎迄,因此運(yùn)行時(shí)常量池也是每個(gè)類都有一個(gè)。我們常說的常量池隆圆,就是指方法區(qū)中的運(yùn)行時(shí)常量池漱挚。

運(yùn)行時(shí)常量池相對(duì)于Class文件常量池的重要特征是具有動(dòng)態(tài)性。除了在編譯器產(chǎn)生的常量可以進(jìn)入運(yùn)行時(shí)常量池外渺氧,還可以在運(yùn)行期間將新的常量放入池中旨涝,比如String 的 intern方法。

(2)運(yùn)行時(shí)常量池保存在JVM哪個(gè)區(qū)域侣背?
位于方法區(qū)白华,Java虛擬機(jī)規(guī)范中將方法區(qū)描述為堆的邏輯部分,所以實(shí)際上還是在堆中贩耐。

(3)Class常量池中保存的是什么弧腥?
方法區(qū)的一部分。Class文件中除了有類的版本潮太、字段管搪、方法、接口等描述信息外,還有常量池(Constant Pool Table)抛蚤,存放編譯期生成的各種字面量和符號(hào)引用台谢,這部分內(nèi)容將在類加載后進(jìn)入方法區(qū)的運(yùn)行時(shí)常量池。也就是說運(yùn)行時(shí)常量池是class常量池的另一個(gè)版本岁经。

但是朋沮,這個(gè)“進(jìn)入”過程,并不會(huì)直接把所有類中定義的常量全部都加載進(jìn)來缀壤,而是會(huì)做個(gè)比較樊拓,如果需要加到字符串常量池中的字符串已經(jīng)存在,那么就不需要再把字符串字面量加載進(jìn)來了塘慕。

推薦閱讀
https://www.zhihu.com/question/29884421
https://www.zhihu.com/question/57109429/answer/151717241
https://www.zhihu.com/question/55994121/answer/147296098
https://blog.csdn.net/zm13007310400/article/details/77534349

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末筋夏,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子图呢,更是在濱河造成了極大的恐慌条篷,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,525評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蛤织,死亡現(xiàn)場(chǎng)離奇詭異赴叹,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)指蚜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門乞巧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人摊鸡,你說我怎么就攤上這事绽媒。” “怎么了免猾?”我有些...
    開封第一講書人閱讀 164,862評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵是辕,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我猎提,道長(zhǎng)免糕,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,728評(píng)論 1 294
  • 正文 為了忘掉前任忧侧,我火速辦了婚禮,結(jié)果婚禮上牌芋,老公的妹妹穿的比我還像新娘蚓炬。我一直安慰自己,他們只是感情好躺屁,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,743評(píng)論 6 392
  • 文/花漫 我一把揭開白布肯夏。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪驯击。 梳的紋絲不亂的頭發(fā)上烁兰,一...
    開封第一講書人閱讀 51,590評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音徊都,去河邊找鬼沪斟。 笑死,一個(gè)胖子當(dāng)著我的面吹牛暇矫,可吹牛的內(nèi)容都是我干的主之。 我是一名探鬼主播,決...
    沈念sama閱讀 40,330評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼李根,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼槽奕!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起房轿,我...
    開封第一講書人閱讀 39,244評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤粤攒,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后囱持,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體夯接,經(jīng)...
    沈念sama閱讀 45,693評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,885評(píng)論 3 336
  • 正文 我和宋清朗相戀三年洪唐,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了钻蹬。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,001評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡凭需,死狀恐怖问欠,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情粒蜈,我是刑警寧澤顺献,帶...
    沈念sama閱讀 35,723評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站枯怖,受9級(jí)特大地震影響注整,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜度硝,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,343評(píng)論 3 330
  • 文/蒙蒙 一肿轨、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蕊程,春花似錦椒袍、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽玫恳。三九已至,卻和暖如春优俘,著一層夾襖步出監(jiān)牢的瞬間京办,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工帆焕, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留惭婿,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,191評(píng)論 3 370
  • 正文 我出身青樓视搏,卻偏偏與公主長(zhǎng)得像审孽,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子浑娜,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,955評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • ??需要說明的一點(diǎn)是佑力,這篇文章是以《深入理解Java虛擬機(jī)》第二版這本書為基礎(chǔ)的,這里假設(shè)大家已經(jīng)了解了JVM的運(yùn)...
    Geeks_Liu閱讀 14,019評(píng)論 5 44
  • 這篇文章是我之前翻閱了不少的書籍以及從網(wǎng)絡(luò)上收集的一些資料的整理筋遭,因此不免有一些不準(zhǔn)確的地方打颤,同時(shí)不同JDK版本的...
    高廣超閱讀 15,604評(píng)論 3 83
  • 本文跟大家聊聊JVM的內(nèi)部結(jié)構(gòu),從組件中的多線程處理漓滔,JVM系統(tǒng)線程编饺,局部變量數(shù)組等方面進(jìn)行解析 JVM JVM ...
    認(rèn)真期待閱讀 469評(píng)論 0 1
  • 找了大半天豁鲤,沒有合適的配圖秽誊。干脆就這樣純文字吧。月月在懷里熟睡讓我一點(diǎn)點(diǎn)找回被需要的感覺琳骡。 一直以來锅论,我并不容易被...
    久久桃花閱讀 240評(píng)論 0 1
  • 小燕感恩日記(第24天)2018.6.11 感恩,開啟豐盛富足的人生楣号。 感恩今天花出去的錢寶寶為我換來美味...
    小燕十豐盛富足的人生閱讀 149評(píng)論 0 2