站長(zhǎng)資訊網(wǎng)
        最全最豐富的資訊網(wǎng)站

        深入解析JAVA中字符串常量池和緩沖池理解與作用

        本篇文章給大家?guī)砹岁P(guān)于java的相關(guān)知識(shí),其中主要介紹了字符串常量池和緩沖池的理解與作用,字符串池與常量池是完全不同的兩個(gè)東西,但是很多地方都喜歡把它們混為一談,很容易讓初學(xué)者產(chǎn)生誤解,在這里我想好好討論一下它們,希望對(duì)大家有幫助。

        深入解析JAVA中字符串常量池和緩沖池理解與作用

        推薦學(xué)習(xí):《java學(xué)習(xí)教程》

        字符串池也可以被稱為字符串常量池,我認(rèn)為這個(gè)名稱就是產(chǎn)生誤解的根源,有些人說著說著就把字符串三個(gè)字省略了,只剩下了常量池… 所以為了避免誤解,我建議在指代字符串對(duì)象的緩存池的時(shí)候,就直接稱之為字符串池

        1 常量池

        常量池分為兩個(gè)類型,一是.class文件中靜態(tài)的常量池,二是.class文件中的靜態(tài)常量池被加載到JVM中而形成的運(yùn)行時(shí)常量池。

        1.1 靜態(tài)常量池

        .class文件中的常量池可以看作一個(gè)數(shù)組,數(shù)組中存儲(chǔ)了一些常量,當(dāng)需要在字節(jié)碼指令中用到這個(gè)常量的時(shí)候,就通過數(shù)組的索引來訪問它。

        看下面的代碼:

         String m = "hellohellohellohellohello";  String n = "hellohellohellohellohello";

        它在字節(jié)碼中將會(huì)是這種形式:

         // 常量池:  #1 hellohellohellohellohello  #2 ...  ...  ----------------------------    String m = #1;  String n = #1;

        當(dāng)然,這只是一個(gè)簡(jiǎn)化的版本,實(shí)際上要更加復(fù)雜 (實(shí)際的版本可以看文章末尾參考資料部分里面貼出的那個(gè)回答,目前可以先只考慮簡(jiǎn)化的版本)

        注意,在這個(gè)里面存儲(chǔ)的字符串常量只是一個(gè)簡(jiǎn)單的UTF8編碼的字節(jié)序列,而不是Java的字符串對(duì)象,它就和你在一個(gè)txt文本中存儲(chǔ)的字符串一樣,我們用UTF8格式來打開一個(gè).class文件,可以看到hellohellohellohellohello是可以被解析的:深入解析JAVA中字符串常量池和緩沖池理解與作用

        1.2 運(yùn)行時(shí)常量池

        理解了靜態(tài)的常量池之后,運(yùn)行時(shí)常量池就很容易想明白了。簡(jiǎn)單來說,運(yùn)行時(shí)常量池就是.class文件中的靜態(tài)常量池在JVM中的運(yùn)行時(shí)表示,每一個(gè).class文件的靜態(tài)常量池都會(huì)生成一個(gè)對(duì)應(yīng)的運(yùn)行時(shí)常量池。等到JVM在解釋String m = #1這條指令時(shí),它可以去這個(gè)類的運(yùn)行時(shí)常量池中查找#1的定義。

        2 字符串池

        字符串池是Java為了重用String對(duì)象而設(shè)置的一個(gè)緩存池,Java1.7之前設(shè)置在方法區(qū)上,保存的是String對(duì)象;Java1.7之后設(shè)置在堆上,保存的是String對(duì)象的引用,String對(duì)象本身存在于堆上的其他位置。下文中以Java1.7之后的情況為標(biāo)準(zhǔn)。

        繼續(xù)上面的例子。當(dāng)JVM在解釋String m = #1時(shí),它已經(jīng)從運(yùn)行時(shí)常量池拿到了相應(yīng)的UTF8序列,接下來,它會(huì)在字符串池中尋找和這個(gè)UTF8序列對(duì)應(yīng)的String對(duì)象,并把這個(gè)對(duì)象的引用賦值給m。你可能會(huì)好奇這個(gè)String被創(chuàng)建的時(shí)機(jī),根據(jù)R大的這篇文章,在這條語句所在的類被加載時(shí),如果字符串池中已經(jīng)存在對(duì)應(yīng)的對(duì)象了,那么就什么都不做,如果不存在,就會(huì)創(chuàng)建一個(gè)對(duì)應(yīng)的String對(duì)象,并把其引用放入池中。

        除了字符串池,IntegerLong等Wrapper類型也有自己的緩存池,比如Integer會(huì)緩存從-128~127的Integer對(duì)象,當(dāng)使用字面量賦值或者Integer.valueOf()時(shí),如果池中存在相應(yīng)的對(duì)象,就會(huì)返回池中的對(duì)象,只有當(dāng)池中沒有時(shí)才會(huì)在堆上創(chuàng)建新對(duì)象。

        不過,和字符串池不同的時(shí),這些Wrapper池不會(huì)像字符串池一樣可以增長(zhǎng),也就是池中的對(duì)象數(shù)目是固定的,Integer池中只會(huì)有-128~127。

        基本類型對(duì)應(yīng)的緩沖池如下:

        boolean values true and false  all byte values  short values between -128 and 127  int values between -128 and 127  char in the range u0000 to u007F

        在 jdk 1.8 所有的數(shù)值類緩沖池中,Integer 的緩沖池 IntegerCache 很特殊,這個(gè)緩沖池的下界是 – 128,上界默認(rèn)是 127,但是這個(gè)上界是可調(diào)的,在啟動(dòng) jvm 的時(shí)候,通過 -XX:AutoBoxCacheMax= 來指定這個(gè)緩沖池的大小,該選項(xiàng)在 JVM 初始化的時(shí)候會(huì)設(shè)定一個(gè)名為 java.lang.IntegerCache.high 系統(tǒng)屬性,然后 IntegerCache 初始化的時(shí)候就會(huì)讀取該系統(tǒng)屬性來決定上界。

        推薦學(xué)習(xí):《java教程》

        贊(0)
        分享到: 更多 (0)
        網(wǎng)站地圖   滬ICP備18035694號(hào)-2    滬公網(wǎng)安備31011702889846號(hào)
        主站蜘蛛池模板: 精品无码人妻夜人多侵犯18| 国产精品 91 第一页| 国产精品久久影院| 无码人妻精品一区二区三区99不卡 | 亚洲国产成人精品女人久久久 | 亚洲精品国产成人影院| 久久精品人人做人人爽电影| 色妞ww精品视频7777| 无码人妻精品一区二区蜜桃百度 | 亚洲精品国产品国语在线| 国产在线观看一区二区三区精品| 2022年国产精品久久久久| 蜜国产精品jk白丝AV网站| 少妇亚洲免费精品| 免费精品视频在线| 精品视频一区二区三区四区五区| 香蕉久久夜色精品国产小说| 国产精品久久网| 99久久精品影院老鸭窝| 精品一区二区三区波多野结衣| 一级做a爰黑人又硬又粗免费看51社区国产精品视 | 久久亚洲国产精品五月天婷| 狠狠精品干练久久久无码中文字幕 | 久久99热国产这有精品| 成人午夜精品视频在线观看| 国产精品日本一区二区不卡视频 | 久久精品aⅴ无码中文字字幕重口 久久精品a亚洲国产v高清不卡 | 国产精品视频分类一区| 91精品国产福利尤物| 精品国产三级a∨在线| 久久66热人妻偷产精品9| 精品免费久久久久久久| 国精品无码一区二区三区在线| 久久精品国产网红主播| 久久精品蜜芽亚洲国产AV| 国产精品亚洲а∨无码播放| 国产乱码精品一区二区三区中文| 精品久久久久久成人AV| 国产91精品在线观看| 亚洲国语精品自产拍在线观看| 国产99久久久国产精品~~牛 |