50000; time = 0.019 sec 100000; time = 0.009 sec 150000; time = 0.009 sec 200000; time = 0.009 sec 250000; time = 0.009 sec 300000; time = 0.009 sec 350000; time = 0.011 sec 400000; time = 0.012 sec 450000; time = 0.01 sec 500000; time = 0.013 sec 550000; time = 0.013 sec 600000; time = 0.014 sec 650000; time = 0.018 sec 700000; time = 0.015 sec 750000; time = 0.029 sec 800000; time = 0.018 sec 850000; time = 0.02 sec 900000; time = 0.017 sec 950000; time = 0.018 sec 1000000; time = 0.021 secJava虛擬主機(jī)上測試代碼 這篇文章的測試代碼很簡單,一個方法中循環(huán)創(chuàng)建并保留新字符串。你可以測量它保留 10000 個字符串所需要的時間。最好配合 -verbose:gc JVM 參數(shù)來運行這個測試,這樣可以查看垃圾收集是何時以及如何發(fā)生的。另外最好使用 -Xmx 參數(shù)來執(zhí)行堆的最大值。 這里有兩個測試:testStringPoolGarbageCollection 將顯示 JVM 字符串池被垃圾收集 — 檢查垃圾收集日志消息。在 Java 6 的默認(rèn) PermGen 大小配置上,這個測試會失敗,因此最好增加這個值,或者更新測試方法,或者使用 Java 7. 第二個測試顯示內(nèi)存中保留了多少字符串。在 Java 6 中執(zhí)行需要兩個不同的內(nèi)存配置 比如: -Xmx128M 以及 -Xmx1280M (10 倍以上)。你可能發(fā)現(xiàn)這個值不會影響放入池中字符串的數(shù)量。另一方面,在 Java 7 中你能夠在堆中填滿你的字符串。
/** - Testing String.intern. * - Run this class at least with -verbose:gc JVM parameter. */ public class InternTest { public static void main( String[] args ) { testStringPoolGarbageCollection(); testLongLoop(); } /** - Use this method to see where interned strings are stored - and how many of them can you fit for the given heap size. */ private static void testLongLoop() { test( 1000 * 1000 * 1000 ); //uncomment the following line to see the hand-written cache performance //testManual( 1000 * 1000 * 1000 ); } /** - Use this method to check that not used interned strings are garbage collected. */ private static void testStringPoolGarbageCollection() { //first method call - use it as a reference test( 1000 * 1000 ); //we are going to clean the cache here. System.gc(); //check the memory consumption and how long does it take to intern strings //in the second method call. test( 1000 * 1000 ); } private static void test( final int cnt ) { final Listlst = new ArrayList ( 100 ); long start = System.currentTimeMillis(); for ( int i = 0; i < cnt; ++i ) { final String str = "Very long test string, which tells you about something " + "very-very important, definitely deserving to be interned #" + i; //uncomment the following line to test dependency from string length // final String str = Integer.toString( i ); lst.add( str.intern() ); if ( i % 10000 == 0 ) { System.out.println( i + "; time = " + ( System.currentTimeMillis() - start ) / 1000.0 + " sec" ); start = System.currentTimeMillis(); } } System.out.println( "Total length = " + lst.size() ); } private static final WeakHashMap > s_manualCache = new WeakHashMap >( 100000 ); private static String manualIntern( final String str ) { final WeakReference cached = s_manualCache.get( str ); if ( cached != null ) { final String value = cached.get(); if ( value != null ) return value; } s_manualCache.put( str, new WeakReference ( str ) ); return str; } private static void testManual( final int cnt ) { final List lst = new ArrayList ( 100 ); long start = System.currentTimeMillis(); for ( int i = 0; i < cnt; ++i ) { final String str = "Very long test string, which tells you about something " + "very-very important, definitely deserving to be interned #" + i; lst.add( manualIntern( str ) ); if ( i % 10000 == 0 ) { System.out.println( i + "; manual time = " + ( System.currentTimeMillis() - start ) / 1000.0 + " sec" ); start = System.currentTimeMillis(); } } System.out.println( "Total length = " + lst.size() ); } }
總結(jié) java主機(jī),java空間,java服務(wù)器, jsp虛擬主機(jī), jsp網(wǎng)站空間, 成都jsp虛擬主機(jī), 成都jsp網(wǎng)站空間
由于 Java 6 中使用固定的內(nèi)存大。≒ermGen)因此不要使用 String.intern() 方法 Java7 和 8 在堆內(nèi)存中實現(xiàn)字符串池。這以為這字符串池的內(nèi)存限制等于應(yīng)用程序的內(nèi)存限制。 在 Java 7 和 8 中使用 -XX:StringTableSize 來設(shè)置字符串池 Map 的大小。它是固定的,因為它使用 HashMap 實現(xiàn)。近似于你應(yīng)用單獨的字符串個數(shù)(你希望保留的)并且設(shè)置池的大小為最接近的質(zhì)數(shù)并乘以 2 (減少碰撞的可能性)。它是的 String.intern 可以使用相同(固定)的時間并且在每次插入時消耗更小的內(nèi)存(同樣的任務(wù),使用java WeakHashMap將消耗4-5倍的內(nèi)存)。 在 Java 6 和 7(Java7u40以前) 中 -XX:StringTableSize 參數(shù)的值是 1009。Java7u40 以后這個值調(diào)整為 60013 (Java 8 中使用相同的值) 如果你不確定字符串池的用量,參考:-XX:+PrintStringTableStatistics JVM 參數(shù),當(dāng)你的應(yīng)用掛掉時它告訴你字符串池的使用量信息。