String.intern原則
String.intern():
此方法是一個Native方法
底層呼叫C 的StringTable::intern方法實作
當透過語句str.intern()呼叫intern()方法後
JVM 就會在目前類別的常數池中尋找是否存在與str等值的String
若存在則直接傳回常數池中對應Strnig的引用
若不存在,則會在常數池中創建一個等值的String
然後返回這個String在常數池中的引用
# -------------- -------------------------------------------------
因此,只要是等值的String物件
使用intern()方法傳回的都是常數池中同一個String引用
所以,這些等值的String物件透過intern()後使用==是可以匹配的
JDK6中String.intern()
Jdk6中常數池位於PermGen(永久代)中
PermGen是一塊主要用於存放已載入的類別資訊和字串池的大小固定的區域
---------------------------------- ----------------------------------------
運行intern()方法時
當常數池中不存在等值的字串,JVM就會在常數池中建立一個等值的字串
然後傳回該字串的引用
除此以外,JVM 會自動在常數池中保存一份先前已使用過的字串集合
Jdk6中使用intern()方法的主要問題就在於常數池被保存在PermGen(永久代)中注意事項:
首先PermGen是一塊大小固定的區域,一般不同的平台PermGen的預設大小也不相同,
大致在32M到96M之間。
所以不能對不受控制的運行時字串(如用戶輸入資訊等)使用intern()方法,
否則很有可能會引發PermGen記憶體溢出;
其次String物件保存在Java堆區,Java堆區與PermGen是物理隔離的,
因此如果對多個不等值的字串物件執行intern操作,
則會導致記憶體中存在許多重複的字串,會造成效能損失
JDK7中String.intern()
Jdk7將常數池從PermGen區移到了Java堆區
運行intern操作
當常數池已經存在該字串,則直接傳回字串引用
否則複製該字串物件的引用到常數池中並傳回
堆區的大小一般不受限,所以將常數池從PremGen區移到堆區使得常數池的使用不再受限於固定大小
除此之外,位於堆區的常數池中的物件可以被垃圾回收
當常數池中的字串不再存在指向它的引用時,JVM就會回收該字串
可以使用-XX:StringTableSize 虛擬機參數設定字串池的map大小
字串池內部實作為一個HashMap
所以當能夠確定程式中需要intern的字串數目時
可以將該map的size設定為所需數目*2(減少hash衝突)
這樣就可以使得String.intern()每次都只需要常數時間和
相當小的記憶體就能夠將一個String存入字串池中
String.intern()方法的功能:
其功能手動將字串放入常數池中
以上是java中String.intern()方法有什麼功能的詳細內容。更多資訊請關注PHP中文網其他相關文章!