前些日了,对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. WPF编程,自定义鼠标形状的一种方法。

    原文:WPF编程,自定义鼠标形状的一种方法. 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net/qq_43307934/article/details/8727 ...

  2. 【转】从Shell脚本内部将所有标准输出及标准错误显示在屏幕并同时写入文件的方法

    如果全部都要重定向的话每一条命令后面>>并不方便,可以这么做.在开头就声明 exec 1>>$log_file表示将脚本中所有的正确输出全部追加到$log_file,错误信息会 ...

  3. Lambda学习---方法引用和其他基本应用

    package com.zx; import java.util.*; import java.util.function.*; import java.util.stream.Collectors; ...

  4. JavaScript快速入门-ECMAScript本地对象(Number)

    Number 对象是原始数值的包装对象. 创建一个Number对象:var myNum=new Number(value); 注意: 1.参数 value 是要创建的 Number 对象的数值,或是要 ...

  5. CentOS 6.8 安装Maven

    1.下载maven安装包到developer文件目录下 2,解压缩maven,命令: -bin.tar.gz 3.配置maven路径到环境变量中 export JAVA_HOME=/usr/java/ ...

  6. C++基础知识(3)

    C++内置的数据类型:基本类型.复合类型 基本类型:整型,浮点型,字符型 复合类型:数组,字符串,指针和结构 复合数据类型是在基本数据类型的基础上创建的 要知道系统中整数的最大长度,可以在程序中使用C ...

  7. 重温jsp①

    Jsp就是一个servlet servlet的缺点 不适合设置html响应体,需要response.Getwriter.print(); 优点:动态资源,可以编程. Jsp:在原有的html中加入了J ...

  8. Spark 实践——用决策树算法预测森林植被

    本文基于<Spark 高级数据分析>第4章 用决策树算法预测森林植被集. 完整代码见 https://github.com/libaoquan95/aasPractice/tree/mas ...

  9. yum 安装mongodb mysql

    // 云环境下更新包 (center os)yum update (多更有益) 修改yum包管理配置:vi /etc/yum.repos.d/mongodb-org-3.4.repo // 会自动新建 ...

  10. ElasticSearch 2 (24) - 语言处理系列之停用词:性能与精度

    ElasticSearch 2 (24) - 语言处理系列之停用词:性能与精度 摘要 在信息检索早期,磁盘和内存相较我们今天的使用只是很小的一部分.将索引空间保持在一个较小的水平是至关重要的,节省每个 ...