Java8中的G1垃圾收集器的字符串重複數據刪除

字符串重複

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日誌中就可以打印出這些信息來。

Java8中的G1垃圾收集器的字符串重複數據刪除

總結

如果你的應用使用的是G1收集器,並且JDK的版本大於 JDK 8 update 20,那麼可以嘗試開啟-XX:+UseStringDeduplication,如果你的應用中存在大量長時間存活的對象,那結果一定還不錯。


分享到:


相關文章: