Java性能优化实例


一个Java程序, 之前运行的非常好,速度也很快, 结果换一个场合却变成慢的要死. 从一个url读取一个70到100KB的文件要几分钟!

可能和服务器有关系, 之前同样的代码在另一个服务器上下载基本看不出延迟, 也可能是其他的软件占用网络资源, 我将其他的占用网速的应用关掉, 快了一点, 但只是一点点, 速度仍然不能容忍.

只好研究代码, 如下

            InputStream in url.openStream();
            FileOutputStream fos new FileOutputStream(filename);
            int readed;
            
            while ( (readed in.read(b)) != -1)
            {
                //System.out.println("avaiable:" + in.available() + "readed:" + readed);
                fos.write(b,0,readed);//fos能否写字符串?
            }
            
            fos.close();

第一点想到的是可能没有使用缓冲, 改之

            BufferedInputStream reader new BufferedInputStream(  url.openStream() );

            FileOutputStream fos new FileOutputStream(filename);
            outln("[start read from url]");
            int readed;

            while ( (readed reader.read(b)) != -1)
            {
                fos.write(b,0,readed);
            }
            
            fos.close();

还是不行, 唯一影响速度的只可能是while循环, 所以又加了一句:

            while ( (readed reader.read(b)) != -1)
            {
                
                outln("readed"+readed);
                fos.write(b,0,readed);
            }

结果:

[start read from url]
readed2048
readed2048
readed2048
readed2048
readed301
readed2048
readed2048
readed2048
readed2048
readed520
readed2048
readed2048
readed2048
readed2048
readed520
readed2048
readed2048
readed2048
readed2048
readed2048
readed2048
readed2048
readed2048
readed2048
readed2048
readed1300
readed2048
readed2048
readed2048
readed2048
readed2048
readed2048
readed2048
readed2048
readed2048
readed1896
readed2048
readed2048
readed2048
readed2048
readed520
readed2048
readed2048
readed2048
readed2048
readed520
readed2048
readed2048
readed2048
readed2048
readed2048
readed2048
readed2048
readed1636
readed2048
readed2048
readed2048
readed2048
readed520
readed1452
readed2048
readed2048
readed1712
readed2048
readed2048
readed2048
readed2048
readed2048
readed2048
readed2048
readed184
readed2048
readed2048
readed2048
readed1116
readed2048
readed856
readed2048
readed2048
readed1712
readed1452
readed2048
readed2048
readed260
readed2048
readed856
readed2048
readed856
readed2048
readed856
readed2048
readed2048
readed260
readed2048
readed2048
readed1712
readed1452
readed2048
readed2048
readed260
readed2048
readed2048
readed2048
readed1116
readed2048
readed856
readed1452
readed2048
readed2048
readed2048
readed1116
readed2048
readed2048
readed1712
readed2048
readed2048
readed2048
readed2048
readed520
readed2048
readed856
readed1452
readed2048
readed856
readed2048
readed2048
readed260
readed2048
readed856
readed1452
readed2048
readed2048
readed1712
readed2048
readed2048
readed1712
readed2048
readed2048
readed260
readed2048
readed2048
readed2048
readed1116
readed1452
readed2048
readed2048
readed260
readed2048
readed2048
readed1712
readed2048
readed2048
readed1712
readed2048
readed2048
readed2048
readed1116
readed1452
readed2048
readed856
readed2048
readed2048
readed1712
readed2048
readed2048
readed260
readed2048
readed2048
readed2048
readed2048
readed520
readed1452
readed2048
readed2048
readed1712
readed2048
readed2048
readed260
readed2048
readed2048
readed805
[saving screen shot img large ],file name is:01319504230_21.jpg

这就是问题的症结所在.b字节数组我设置的是2048字节, 最大的延时发生在两次read操作之间, 很多时候一次都无法读满整个数组, 有时候一次只能读几百字节, 但是延时和读取2048字节差不多.

只好大幅度的增加缓冲区大小, 对于b数组设置为100kb,对于BufferedInputStream设置为200KB. 注意, 虽然不太清楚JVM的堆内存大小, 但是直接使用200KB做缓冲区会导致OoutOfMemoryError, 增加jvm的内存,用如下方法:

java -Xms25M -Xmx512M SearchCrawler

运行结果

[start read from url]
readed11325
readed43560
readed22270
[saving screen shot img large ],file name is:1289443046_1.jpg

[start read from url]
readed12777
readed39011
[saving screen shot img large ],file name is:1289443046_2.jpg

[start read from url]
readed12776
readed66792
readed40665
[saving screen shot img large ],file name is:1289443046_3.jpg

相当好的结果, 似乎100kb, 200kb的设置都太大了, 每次读取的字节数很少超过50kb的.极好的经验, 记之.