字符串重複
JDK開發組研究得出的一組有趣的統計數據:
1.java應用內存裡面的字符串佔比大概是25%。
2.java應用內存裡面的字符串有13.5%是重複的。
3.字符串的平均長度是45。
什麼是重複字符串呢?
看下面的代碼:
<code>
1. `String string1 = newString("Hello King");`
2. `String string2 = newString("Hello King");`
/<code>
兩個字符串對象string1和string2,它們的內容是一樣的,都是Hello King,但是string1和string2是兩個不同的對象。
string1.equals(String2)=true,但是(string1==string2) =false,所以string1和string2就是所謂的重複對象。
Java處理的方式
1.通過使用String.intern()方法 2.通過啟用字符串重複數據刪除(僅適用於G1垃圾收集器)
啟用字符串重複數據刪除
此功能此後僅在Java8上可用,並且僅在使用G1垃圾收集器時才能啟用。
使用以下標誌可以啟用重複數據刪除。
<code>
1. `-XX:+UseG1GC-XX:+UseStringDeduplication`
/<code>
注意事項
(1)只適用於G1收集器
JVM中有很多的GC收集器(串行、並行、CMS等等),XX:+UseStringDeduplication只能用在G1收集器上,如果你是使用的別的收集器需要切換到G1才可以。
(2)只適用於長期存活的對象
XX:+UseStringDeduplication主要是用來消除長時間存活的重複字符串對象,它不會對短期存活的對象做去重。如果字符串的生命週期很短,很可能還沒來記得做去重就已經死亡了。但是,如果你的應用有大量的緩存(尤其是緩存的對象是長時間存活的對象),UseStringDeduplication這個參數就可能非常有用了!
(3)-XX:StringDeduplicationAgeThreshold=3
默認情況下,一個字符串對象經過3次GC以後還存活才會被列為去重的候選對象,可以用-XX:StringDeduplicationAgeThreshold來改變經歷的GC的次數,比如:
<code>
1. `-XX:StringDeduplicationAgeThreshold=6`
/<code>
(4)僅能用於Java 8 update 20以後
只有從Java 8 update 20以後才開始支持這個參數,因此,如果你的JDK版本比較老的話就沒法用這個功能了。
(5)-XX:+PrintStringDeduplicationStatistics查看去重信息
如果你想查看字符串去重的一些統計信息,比如說去重花了多長時間、多少重複字符串被去重、節省了多少內存等等,可以傳遞-XX:+PrintStringDeduplicationStatistics這個參數給JVM,在GC日誌中就可以打印出這些信息來。
總結
如果你的應用使用的是G1收集器,並且JDK的版本大於 JDK 8 update 20,那麼可以嘗試開啟-XX:+UseStringDeduplication,如果你的應用中存在大量長時間存活的對象,那結果一定還不錯。
閱讀更多 享學課堂online 的文章