前些日了,对AIO与NIO的并发性能进行了比较,在低并发的情况下,NIO性能表现比AIO好一些,主要原因是,NIO中可以使用FileChannel.transferTo(long position, long count, WritableByteChannel target),这个方法可以对传输文件数据有很大的性能提升。

在AIO中,没办法使用FileChannel.transferTo(...),只能使用ByteBuffer来做中转,我一开始使用的ByteBuffer.allocate(16 * 1024),也就是16KB的缓存区。

由于上面的原因,所以NIO在不是很高的并发情况下,性能比AIO表现的好一些。

昨天,我还写了一篇文章:AsynchronousFileChannel 使用的默认线程池的疑问

今天早上,我试着将ByteBuffer由原来固定的16KB,更改为一个与传输的文件大小有关的字节缓存区。

相关代码如下:

//如果文件大小<1M,直接返回一个 fileSize + headerSize
 //如果文件大小>=1M,直接返回一个(fileSize + headerSize) / 2, 也就是最多保证分两次传输完数据
 private ByteBuffer allocateByteBuffer(int fileSize, int headerSize)
 {
  if(fileSize < 1024 * 1024)
  {
   return ByteBuffer.allocate(fileSize + headerSize);
  }
  else
  {
   return ByteBuffer.allocate((fileSize + headerSize) / 2 + 1); //这所以 +1, 因为 11 / 2 = 5,为了保证两次传完, + 1 可保证这一点
  }
 }

然后经过测试发现,在低并发情况下,性能上升了很多,终于赶上了NIO的性能,同时观察“任务管理器”中的进程使用的线程数也下降了很多,真是一举两得,这让我兴奋了好一会儿,

经过冷静的分析,我得出的结论:

之所以将ByteBuffer的大小设置为与传输的文件大小有关的缓存区后性能得到了很大的提升,主要与AIO的“写操作”有关。

举个例子:

在AIO的“写操作”中,如果我们设置ByteBuffer为一个固定的16KB的缓存区,当我们传输一个160KB的文件时,AIO的“写操作”需要执行10次“回调”。每1次的回调都是在系统默认的一个线程池中运行的,回调的次数与线程池中的线程数是成正比的。

如是我们将ByteBuffer设置为160KB,在进行AIO的“写操作”时,系统只执行了一次“回调”,回调的次数减少了,线程池的容量也不再需要那么多了,性能同时也上升了。

不过,经过测试也发现,ByteBuffer的容量也不能无限制的根据文件大小一设置,如果一个文件超过1M,还是最好设置为最大不超过1M的缓存区比较好,因为测试发现,如果设置一个很大的缓存区,比如5M,在高并发的时候,系统内存会很快用完,直接抛出: OutOfMemoryError

-------------------------------------------------------------------------------------------------

AIO进程占用的线程数与文件IO和网络IO有非常大的关系,当高并发的时候,网络IO达到瓶颈,这个时候很多任务都没有完成(正在完成中),占用的线程自然就会不断的上升。

2012-07-10

Java: 扩大字节缓存区的大小,提升AIO的处理性能(并发性能)的更多相关文章

  1. java输入输出 -- java NIO之缓存区Buffer

    一.简介 java NIO相关类在jdk1.4被引入,用于提高I/O的效率.java NIO包含很多东西,但核心的东西不外乎Buffer.channel和selector.本文先来看Buffer的实现 ...

  2. Java开发笔记(九十三)深入理解字节缓存

    前面介绍了文件通道的读写操作,其中用到字节缓存ByteBuffer,它是位于通道内部的存储空间,也是通道唯一可用的存储形式.ByteBuffer有两种构建方式,一种是调用静态方法wrap,根据输入的字 ...

  3. 文件分片 浏览器文件大小限制 自定义请求头 在一个资源的加载进度停止之后被触发 arrayBuffer 异步 二进制数据缓存区

    js 整数限制 浏览器文件大小限制 https://w3c.github.io/FileAPI/#dom-blob-arraybuffer https://developer.mozilla.org/ ...

  4. 按字节读取txt文件缓存区大小设置多少比较好?

    读取 txt 文件常规写法有逐行读取和按照字节缓存读取,那么按照字节缓存读取时,设置缓存区多大比较好呢?百度了一下,没发现有说这个问题的,自测了一把,以事实说话. 常规读取方法如下: // 字节流读取 ...

  5. JAVA之旅(十七)——StringBuffer的概述,存储,删除,获取,修改,反转,将缓存区的数据存储到数组中,StringBuilder

    JAVA之旅(十七)--StringBuffer的概述,存储,删除,获取,修改,反转,将缓存区的数据存储到数组中,StringBuilder 讲完String,我们来聊聊他的小兄弟 一.StringB ...

  6. IntelliJ IDEA修改Output输出缓存区大小【应对:too much output to process】

    IntelliJ IDEA默认的Output输出缓存区大小只有1024KB,超过大小限制的就会被清除,而且还会显示[too much output to process],可通过如下配置界面进行修改O ...

  7. Java NIO------基础理论之缓存区

    1.概述:NIO我的理解就是 New IO,是API1.4里提供的新的API,为所有的原始类型做缓存支持. NIO主要的核心组成部分: Buffer(缓存) Channels(通道) Selector ...

  8. 【MINA】缓存区ByteBuffer和IOBuffer你要了解的常用知识

    mina中IOBuffer是Nio中ByteBuffer的衍生类,主要是解决Bytebuffer的两个不足 1.没有提供足够灵活的get/putXXX方法 2.它容量固定,难以写入可变长度的数据 特点 ...

  9. 如何计算Java对象所占内存的大小

    [ 简单总结: 随便一个java项目,引入jar包: lucene-core-4.0.0.jar 如果是 maven项目,直接用如下依赖: <dependency> <groupId ...

随机推荐

  1. 20155237 《JAVA程序设计》实验二(JAVA面向对象程序设计)实验报告

    20155237 <JAVA程序设计>实验二(JAVA面向对象程序设计)实验报告 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S ...

  2. 20155337 《网络对抗》 Exp2 后门原理与实践

    20155337 <网络对抗> Exp2 后门原理与实践 一.基础问题回答 - 例举你能想到的一个后门进入到你系统中的可能方式? 在Unix里,login程序通常用来对telnet来的用户 ...

  3. Spring @Value注入值失败,错误信息提示:Could not resolve placeholder

    问题根源: @Value("${wx.app.config.appid}") public Object appid; 异常信息: Caused by: java.lang.Ill ...

  4. Luogu P1273 有线电视网

    最近写DP写得比较多了 但是POJ上的题目太傻比了而且不想看英文的题面,然后就在Luogu的试炼场里找了一个DP EX专题写了一下(大概3days吧,一天一题差不多) 这是一道比较简单的DP 话说树形 ...

  5. vue-cli 3.0 图片路径问题(何时使用 public 文件夹)

    1. 图片放入public文件夹下时 参考:https://cli.vuejs.org/zh/guide/html-and-static-assets.html#public-%E6%96%87%E4 ...

  6. 设计模式 笔记 状态模式 State

    //---------------------------15/04/28---------------------------- //State  状态模式----对象行为型模式 /* 1:意图: ...

  7. Spring学习(十九)----- Spring与WEB容器整合

    首先可以肯定的是,加载顺序与它们在 web.xml 文件中的先后顺序无关.即不会因为 filter 写在 listener 的前面而会先加载 filter.最终得出的结论是:listener -> ...

  8. Microsoft Dynamics CRM 常用JS语法(已转成vs2017语法提示)

    背景 最近接触到Microsoft Dynamics CRM的开发.前端js是必不可少的部分,奈何没有一个语法提示,点不出来后续的语句. 在vscode上面搜索插件的时候发现,有一个大神写的插件htt ...

  9. Linux shell (6)

    1.linux shell函数: 将一组命令集或语句形成一个可用的块,这些语句块成为函数. 2.shell 函数的组成:  函数名:函数的名字,注意一个脚本中函数名要唯一,否则会引起调用函数紊乱  函 ...

  10. [转]申瓯 JSY2000-06 程控电话交换机呼叫转移设置

    说明:若申瓯程控电话交换机分机有事不在位置上或遇忙分机正忙时为使某些重要来话不丢失,可设置将呼入本机的电话转移至其他分机及公网固定电话或手机.电话交换机使用了本功能不管分机用户在什么地方都能接听到办公 ...