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);

輸出:java

false數組

trueapp

falseui

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

s6同理3d

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

s5 = "haha",由於也是常量,會先在StringTable中查找,找到後s5指向了StringTable中的"haha",所以s4 == s5返回true。對象

 

String.intern()方法,若是String在StringTable中不存在,則能夠將這個String加入StringTable中,並返回這個對象。blog

好比上面的方法中加入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多毫秒

相關文章
相關標籤/搜索