方法區(qū)內(nèi)部包含了運(yùn)行時常量池
常量池
就是一張表,虛擬機(jī)指令根據(jù)這張常量表找到要執(zhí)行的類名升熊,方法名勘高,參數(shù)類型,字面量等信息
運(yùn)行時常量池
把字節(jié)碼文件中的常量池信息放入運(yùn)行時常量池似忧,并把里面的符號地址變?yōu)檎鎸嵉刂?/p>
字符串常量池StringTable的特性
利用字符串池的機(jī)制來避免重復(fù)創(chuàng)建字符串對象
字符串變量拼接的原理是 StringBuilder(1.8):String a = "a"; String b = "b"; String c = a + b;
字符串常量拼接的原理是 編譯器優(yōu)化:String c = "a" + "b";
intern
intern方法的作用就是可以主動將字符串常量池中還沒有的字符串對象放入嘗試將一個字符串放入StringTable中。對于程序中大量存在的字符串丈秩,尤其是存在很多重復(fù)字符串時盯捌,使用intern()可以節(jié)省內(nèi)存空間。
????????1.6:將這個字符串對象嘗試放入串池中蘑秽,如果不存在就放入StringTable并返回StringTable中的地址饺著,如果存在的話就直接返回StringTable中的地址。
????????1.8:嘗試將字符串對象放入StringTable筷狼,如果有則并不會放入瓶籽,如果沒有會創(chuàng)建一個這個對象的引用放入StringTable(而不是直接將該字符串放入stringtable中)匠童,再把StringTable的這個引用返回埂材。
思考:String str = new String("a") + new String("b"); 一共創(chuàng)建了幾個對象?
????對象1: new StringBuilder():凡是變量拼接都會new 一個 StringBuilder
? ? 對象2:new String("a")
? ? 對象3:常量池中的"a":在字節(jié)碼中為ldc
? ? 對象4:new String("b")
? ? 對象5:常量池中的"b":在字節(jié)碼中為ldc
? ? 對象6:StringBuilder的toString():new String("ab")汤求。但toString()的調(diào)用俏险,在字符串常量池中沒有生成"ab"
StringTable 垃圾回收
-XX:+PrintStringTableStatistics 開啟打印StringTable的參數(shù)
StringTable:類似于HashTable的實現(xiàn)(數(shù)組+鏈表),
每個數(shù)組個數(shù)稱為桶buckets
鍵值對個數(shù):number of entries
字符串常量個數(shù):number of literals
StringTable 性能調(diào)優(yōu)
1. 調(diào)整-XX:StringTableSize=桶個數(shù)
2. 考慮將字符串對象是否入池