前几天性能测试的时候发现一个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="";