使用String.intern減少內存使用


最近寫一個程序,從文件中讀取一些字/詞,然后存儲起來供別的類引用。

對每個讀入的詞創建一個String,結果許多同樣內容的也會存儲多份,會占用大量內存。

開始的一個想法是使用map/set來存儲所有遇到的詞,這樣就沒有重復的了。然后別的類只需要引用這些詞就可以了。

這樣還需要一些工作量,經別人介紹,發現了String.intern方法。

例如下面代碼

String a = new String("abc");
String b = new String("abc");
assertNotSame(a, b);

a和b是兩個獨立的對象,它們有各自的存儲。所以not same。

但如果

String a = new String("abc").intern();
String b = new String("abc").intern();
assertSame(a, b);

此時assertSame就會pass。現在a和b其實是一個對象,a == b。它們只是同一個對象的兩個名字。在debug時,可以看到他們的id是一樣的。這樣跟

String a = new String("abc");
String b = a;
assertSame(a, b);

效果是完全一樣的。

intern是一個native的方法,但按照其文檔解釋,應該是JVM維護了一個當前進程曾經出現過的字符串的hash表,在調用intern時,會查詢該表。如果已經存在,則直接返回對該String的引用;如果沒有,則創建一個,並加入到hash中。

在我的代碼中,因為是從文件中讀取的詞,所以只需要在讀取詞后,對每個詞調用下intern再存儲,就可以保證同樣內容的字符串只有一份存儲。更確切的說,只有一個對象。即不僅字符串內容只有一份,其overhead(String類的非內容部分,例如其他成員變量)也只有一份。

另外,如果使用字面量(literal)來定義字符串,則自動會調用intern,從而減少內存占用。例如:

String a = new String("abc");
String b = "abc";
String c = "abc";

assertSame(b, c);
assertNotSame(a, b);

對於字面量定義的b和c都會自動調用intern,(等用於String b = "abc".intern())。所以此時b和c是指向同一個對象。但a不是字面量定義的,所以是獨立對象。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM