簡體   English   中英

真實生活,在Java中使用String.intern()的實際例子?

[英]Real Life, Practical Example of Using String.intern() in Java?

我已經看到很多原始的例子描述了String intern()的工作方式,但我還沒有看到一個可以從中受益的真實用例。

我能想到的唯一情況是擁有一個接收大量請求的Web服務,由於僵化的架構,每個請求都非常相似。 通過intern()在這種情況下使用請求字段名稱,可以顯着減少內存消耗。

任何人都可以提供在生產環境中使用intern()並取得巨大成功的示例嗎? 也許是一個流行的開源產品中的一個例子?

編輯:我指的是手動實習,而不是字符串文字的保證實習等。

如果您有N字符串只能采用K不同的值,其中N遠超過K ,則實習可能非常有用。 現在,不是將N字符串存儲在內存中,而是只存儲K

例如,您可能有一個由5位數組成的ID類型。 因此,只能有10^5不同的值。 假設您現在正在解析一個包含許多ID值引用/交叉引用的大型文檔。 假設這個文件總共有10^9引用(顯然在文檔的其他部分重復了一些引用)。

因此在這種情況下N = 10^9K = 10^5 如果你沒有實習字符串,你將在內存中存儲10^9字符串,其中許多字符串是equals (通過Pigeonhole Principle )。 如果你intern()你在解析文檔時得到的ID字符串,並且你沒有保留對從文檔中讀取的未處理字符串的任何引用(因此它們可以被垃圾收集),那么你將永遠不需要在內存中存儲超過10^5字符串。

不是一個完整的答案,但需要額外的思考( 在這里找到 ):

因此,在這種情況下的主要好處是使用內部字符串的==運算符比使用equals()方法[對於非內部化字符串]快得多。 因此,如果要比較字符串超過一次或三次,請使用intern()方法。

我們有一個生產系統,一次處理數百萬條數據,其中許多都有字符串字段。 我們本來應該是實習生,但有一個錯誤意味着我們沒有。 通過修復錯誤,我們避免了必須進行非常昂貴的(至少6位數,可能是7位)服務器升級。

實習將有益的示例涉及大量字符串,其中:

  • 字符串很可能在多個GC循環中存活,並且
  • 很可能會有大量字符串的多個副本。

典型示例涉及將文本拆分/解析為符號(單詞,標識符,URI),然后將這些符號附加到長壽命數據結構中。 XML處理,編程語言編譯和RDF / OWL三重存儲作為內部可能有益的應用而浮現在腦海中。

但實習並非沒有問題,特別是如果事實證明上述假設不正確:

  • 用於保存實習字符串的池數據結構占用額外空間,
  • 實習需要時間,而且
  • interning不會阻止首先創建重復的字符串。

最后,通過增加需要跟蹤和復制的對象數量,以及增加需要處理的弱引用數量,實習可能會增加GC開銷。 這種間接費用的增加必須與有效實習產生的GC費用減少相平衡。

永遠, 永遠 ,使用用戶提供的數據實習生,因為這可能會導致拒絕服務攻擊(如實習生()的字符串是永遠不會被釋放)。 您可以對用戶提供的字符串進行驗證,但是您再次完成了intern()所需的大部分工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM