java io优化_Java代码的IO优化总结 | 学步园

Java代码的IO优化总结

1、现象:问题描述

在优化MMSC的过程中,发现Java模块在读取IO的时候要等待超时才结束读取的过程,这种操作是一种低效的操作,降低了系统的性能。

2、关键过程:根本原因分析

在Solaris10下查看发现,读取IO需要等待到超时的情况主要集中在读取外部的HTTP请求时候产生,这部分代码主要是Servlet中读取外部提交请求的部分。在Servlet读取外部请求的实现中,我们每次是读取4K,一直读取到输入流结束,读取

Socket输入流的过程中,判断输入流的结束都是读取到输入流结束或者超时作为结束的;另外,还有一个问题,就是每次读取4K后,最终需要拷贝到一个byte[]对象中,这个过程也是一个耗费系统性能的过程,代码如下:

DataInputStream in = new DataInputStream(request.getInputStream());

OutputStream out = response.getOutputStream();

byte[] buffer = new byte[4096];

ByteArrayOutputStream msgBodyStream = new ByteArrayOutputStream(4096);

int n = in.read(buffer);

while (n != -1)

{

msgBodyStream.write(buffer, 0, n);

n = in.read(buffer);

}

byte[] msgBody = msgBodyStream.toByteArray();

上面这段代码中,第一段红色的代码,初始化的ByteArrayOutputStream太小,导致在调用其write方法的时候会进行多次拷贝的操作;第二段红色代码,要读取到n返回-1的时候,大都是等待Socket读取超时,无谓的wait影响系统性能(可以先得到MsgBody的长度,然后直接读取到该长度就可以了,不用等到超时);第三段红色代码中也是牵涉到一个内存拷贝的问题,如果我们直接设置MsgBody的大小,然后将内容直接拷贝到MsgBody中就不会有此问题了。

3、结论:解决方案及效果

所以我们需要对这几个方面进行改进,按照这样的思路,我们可以将Servlet读取外部HTTP请求的代码优化如下:

DataInputStream in = new DataInputStream(request.getInputStream());

OutputStream out = response.getOutputStream();

int length = request.getContentLength();

//如果成功获取HTTP头部设置的消息长度

byte[] msgBody = null;

if (-1 != length)

{

msgBody = new byte[length];

in.readFully(buffer);

}

//HTTP1.1请求可能不设置Content-Length

else

{

buffer = new byte[102400]; //这里假设对外部提交消息大小为102400;

ByteArrayOutputStream msgBodyStream = new

ByteArrayOutputStream(102400);

读取外部HTTP请求;

……

}

按照上述方法实现后,读取外部的HTTP请求不需要等待到Socket超时,并且内存申请及拷贝的操作大为减少,提高了系统的效率。我们对于IO的优化是减少系统进行等待输入流超时的处理,对于读取的内容尽量减少拷贝操作,按照上述方案优化后,系统读取外部HTTP请求的性能得到明显的改善,效果相当明显。

4、经验总结:预防措施和规范建议

IO的读取要尽量获取要读取的内容的长度,而不是等待Socket超时;另外,对于一些OutputStream的操作,使用起来比较方便,但是初始化大小的错误可能导致其write方法会多次内容拷贝的操作,此外,ByteArrayOutputStream.toByteArray方法也建议在处理大容量内存的时候慎用,这会牵涉到一个内存拷贝的问题。这篇文章的主要目的是如何进行io优化,没有考虑恶意攻击的问题。可以根据情况对程序做一定的限制,如:增加一个线程锁,防止过多的并发访问。对int length = request.getContentLength();做大小的限制,防止传入过大的请求。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值