JVM - StringTable


 
StringTable:在方法區中的運行常量池中,會將第一次定義的String存入其中,下次再出現時直接將變量指向里面的值。結構是hash表
 
        String s1 = "ha";
        String s2 = "ha"; String s3 = s1 +s2; String s4 = "ha" + "ha"; String s5 = "haha"; String s6 = new String("haha"); System.out.println(s3 == s4); System.out.println(s4 == s5); System.out.println(s5 == s6);

輸出:

false

true

false

s3本質調用了 new StringBuilder.append("a").append("b").toString(); 聲明了新的引用變量,開辟了新的空間,所以指向的是堆中的對象地址而不是StringTable中的字符串了。

s6同理

s4 = "ha" + "ha";因為是兩個常量拼接,在編譯時就會直接變成"haha"進行處理,進入StringTable

s5 = "haha",因為也是常量,會先在StringTable中查找,找到后s5指向了StringTable中的"haha",因此s4 == s5返回true。

 

String.intern()方法,如果String在StringTable中不存在,則可以將這個String加入StringTable中,並返回這個對象。

比如上面的方法中加入s3.intern(),

        String s1 = "ha";
        String s2 = "ha"; String s3 = s1 +s2; s3.intern(); String s4 = "ha" + "ha"; System.out.println(s3 == s4);

輸出:

true

因為s3的值"haha"被放入了StringTable,s3指向了StringTable的"haha"對象

 

把haha變為main

        String s1 = "ma";
        String s2 = "in";
        String s3 = s1 +s2;
        s3.intern();
        String s4 = "ma" + "in";
        System.out.println(s3 == s4);

輸出:

main String,java等屬於關鍵詞,在一開始就在StringTable中存在了,所以s3.intern沒能插入進去。

 

改回haha,如果再在s3前加入一個String ss = "haha";

        String s1 = "ha";
        String s2 = "ha"; String ss = "haha"; String s3 = s1 +s2; s3.intern(); String s4 = "ha" + "ha"; System.out.println(s3 == s4);

輸出:

false

因為s3.intern()執行時發現StringTable中有了"haha"了,所以沒能加入成功,s3依舊是指向了堆內存中的對象。

 

-Xms500m  設置堆內存為500mb

-XX:StringTableSize=2000  將StringTable中的桶個數設為2000。 hash表桶的數量越多(數組部分長度越長),數據越分散,hashcode撞車的概率越小,速度越快。 默認值是6萬多

-XX:+PrintStringTableStatistics 顯示StringTable的狀況。

 

StringTable有內存回收機制

打開“Run->Edit Configurations”菜單

 

 在VM option(虛擬機設置)中,加入代碼:-XX:StringTableSize=2000 ,點擊ok,然后運行下面的代碼

        long t1 = new Date().getTime();
        String[] a = new String[1000000];
        for(int i=0; i<1000000; i++){
            a[i] = ("" + i).intern();
        }
        long t2 = new Date().getTime();
        System.out.println(t2 - t1);

運行時間為9000多毫秒。

 

然后修改VM option:-XX:StringTableSize=20000,點擊ok,然后再嘗試

運行時間為1000多毫秒

 

然后修改VM option:-XX:StringTableSize=200000,點擊ok,然后再嘗試

運行時間為400多毫秒


免責聲明!

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



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