前幾天性能測試的時候發現一個web 端cpu出現驟降的問題,一直沒有找到緣由,起初懷疑是tomcat的線程數有關,後來有懷疑是跟數據庫的響應時間太長有關係,後來都一一排除了。 java
之因此此問題比較難以定位主要是由於經過現有的監控工具沒法獲知和分析tomcat內部各個線程的佔用資源的狀況。 web
上週裝了一下jprofiler,而後又從新進行了一次壓力測試,終於找到了問題的根源:) 數據庫
主要的資源消耗點是:字符串的拼接上。代碼中時使用」+「來進行字符串鏈接的。 tomcat
(ps:jprofiler監控的粒度很細,可是因爲其自己運行佔用的資源消耗量也很大,所以在進行性能測時不能用其做爲監控工具,在分析問題方面仍是蠻有用的;jconsole是java自帶的監控工具,其在遠程監控應用程序時,不會對程序的性能形成影響,但因爲其監控的粒度仍是有些粗,所以tomcat內部的資源佔用狀況仍是沒法進行分析的) 安全
JAVA中String ,StringBuffer,SrtingBuilder三個對象鏈接字符串的效率。
比較下究竟誰的效率高。由於咱們常常都聽有經驗的人說,避免使用String經過「+」鏈接字符串,特
別是鏈接的次數不少的時候,必定要用StringBuffer,但究竟效率多高,速度多快,我也沒有測試過,
因此我就動手測試下,順便把測試結果跟你們一塊兒分享,但願你們共同討論此問題。
下邊是個人測試代碼,可直接運行: app
public class TestStringConnection { //鏈接時間的設定 private final static int n = 20000; public static void main(String[] args){ TestStringConnection test = new TestStringConnection (); test.testStringTime(n); test.testStringBufferTime(n); test.testStringBuilderTime(n); // //鏈接10次 // test.testStringTime(10); // test.testStringBufferTime(10); // test.testStringBuilderTime(10); // // //鏈接100 // // test.testStringTime(100); // test.testStringBufferTime(100); // test.testStringBuilderTime(100); // // // // //鏈接1000 // // test.testStringTime(1000); // test.testStringBufferTime(1000); // test.testStringBuilderTime(1000); // // // //鏈接5000 // // test.testStringTime(5000); // test.testStringBufferTime(5000); // test.testStringBuilderTime(5000); // // // //鏈接10000 // // test.testStringTime(10000); // test.testStringBufferTime(10000); // test.testStringBuilderTime(10000); // // //鏈接20000 // // test.testStringTime(20000); // test.testStringBufferTime(20000); // test.testStringBuilderTime(20000); } /** *測試String鏈接字符串的時間 */ public void testStringTime(int n){ long start = System.currentTimeMillis(); String a = ""; for(int k=0;k<n;k++ ){ a += "_" + k; } long end = System.currentTimeMillis(); long time = end - start; System.out.println("//////////////////////鏈接"+n+"次" ); System.out.println("String time "+n +":"+ time); //System.out.println("String str:" + str); } /** *測試StringBuffer鏈接字符串的時間 */ public void testStringBufferTime(int n){ long start = System.currentTimeMillis(); StringBuffer b = new StringBuffer() ; for(int k=0;k<n;k++ ){ b.append( "_" + k ); } long end = System.currentTimeMillis(); long time = end - start; System.out.println("StringBuffer time "+n +":"+ time); //System.out.println("StringBuffer str:" + str); } /** *測試StringBuilder鏈接字符串的時間 */ public void testStringBuilderTime(int n){ long start = System.currentTimeMillis(); StringBuilder c = new StringBuilder() ; for(int k=0;k<n;k++ ){ c.append( "_" + k ); } long end = System.currentTimeMillis(); long time = end - start; System.out.println("StringBuilder time " +n +":"+ time); System.out.println("//////////////////////"); //System.out.println("StringBuffer str:" + str); } }
測試環境:eclipse
|
可是爲何String如此慢呢,分下以下簡單片斷 String result="";
result+="ok"; 這段代碼看上去好像沒有什麼問題,可是須要指出的是其性能很低,緣由是java中的String 類不可變的(immutable),這段代碼實際的工做過程會是如何的呢?經過使用javap工具我 們能夠知道其實上面的代碼在編譯成字節碼的時候等同的源代碼是: String result="";