![](/img/trans.png)
[英]Why do I get different results with String.intern() vs. passing String object in Java?
[英]Java 8 String deduplication vs. String.intern()
我正在閱讀Java 8更新20中的字符串重復數據刪除功能( 更多信息 ),但我不確定這是否會使String.intern()
過時。
我知道,這JVM功能需要的G1垃圾收集器,這可能不是很多的選擇,但假設一個使用G1GC, 是有自動重復數據刪除的由JVM完成VS手動有任何差異/優勢/劣勢intern
您字符串 (一個明顯的優點是不必通過調用intern()
來污染代碼)?
考慮到Oracle可能使G1GC成為java 9中的默認GC,這一點尤為有趣
使用此功能,如果您有1000個不同的String對象,所有對象具有相同的內容"abc"
,JVM可以使它們在內部共享相同的char[]
。 但是,您仍然有1000個不同的String
對象。
使用intern()
,您將只有一個String
對象。 因此,如果您關注內存節省, intern()
會更好。 它將節省空間,以及GC時間。
然而,上次我聽說, intern()
的表現並不是那么好。 擁有自己的字符串緩存可能會更好,即使使用ConcurrentHashMap
......但您需要對其進行基准測試以確保。
作為評論參考,請參閱: http : //java-performance.info/string-intern-in-java-6-7-8/ 。 這是非常有見地的參考,我學到了很多,但我不確定它的結論是否“一刀切”。 每個方面都取決於您自己的應用程序的需求 - 強烈建議您測量實際的輸入數據!
主要因素可能取決於您控制的內容:
您是否可以完全控制GC的選擇? 例如,在GUI應用程序中,使用Serial GC仍然有很強的理由。 (該過程的總內存占用空間要低得多 - 對於中等復雜的應用程序,請考慮400 MB與~1 GB,並且更願意釋放內存,例如在使用瞬間激增之后)。 所以你可以選擇它或給你的用戶選擇。 (如果堆仍然很小,暫停不應該是一個大問題)。
你有完全控制代碼嗎? G1GC選項非常適合您無法編輯的第三方庫(和應用程序!)。
第二個考慮因素(根據@ ZhongYu的回答)是String.intern
可以對String
對象本身進行重復數據刪除,而G1GC必須只能去除它們的私有char[]
字段。
第三個考慮因素可能是CPU使用率,例如,如果您的用戶可能會對筆記本電腦電池壽命產生影響。 G1GC將運行一個專門用於重復堆棧的額外線程。 例如,我使用它來運行Eclipse並發現它在啟動后導致初始階段的CPU活動增加(想想1 - 2分鍾)但它確定在一個較小的堆“使用中”並且沒有明顯的(只是眼睛 - 對任務管理器進行計算)此后CPU開銷或減速。 所以我想在CPU內核的某個百分比將被用於重復數據刪除(在?之后?)高內存流失期間。 (當然,如果你到處調用String.intern,可能會有相似的開銷,這也會串行運行,但是......)
您可能不需要在任何地方進行字符串重復數據刪除。 可能只有某些代碼區域:
通過有選擇地使用String.intern
,代碼的其他部分(可能會創建臨時或半臨時字符串)不支付價格。
最后,快速插入Guava實用程序: Interner ,它:
為其他不可變類型提供
String.intern()
等效行為
您也可以將它用於字符串。 內存可能(並且應該)是您最關注的性能問題,因此這可能不經常適用:但是當您需要從某些熱點區域擠出每一滴速度時,我的經驗是基於Java的弱引用即使在調整jvm選項之后,HashMap解決方案也會比JVM的String.intern()
C ++實現略微但一致地運行得更快。 (並且獎勵:您不需要調整JVM選項以擴展到不同的輸入。)
我想介紹另一個關於目標受眾的決策因素:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.