Java: 扩大字节缓存区的大小,提升AIO的处理性能(并发性能)
前些日了,对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的处理性能(并发性能)的更多相关文章
- java输入输出 -- java NIO之缓存区Buffer
一.简介 java NIO相关类在jdk1.4被引入,用于提高I/O的效率.java NIO包含很多东西,但核心的东西不外乎Buffer.channel和selector.本文先来看Buffer的实现 ...
- Java开发笔记(九十三)深入理解字节缓存
前面介绍了文件通道的读写操作,其中用到字节缓存ByteBuffer,它是位于通道内部的存储空间,也是通道唯一可用的存储形式.ByteBuffer有两种构建方式,一种是调用静态方法wrap,根据输入的字 ...
- 文件分片 浏览器文件大小限制 自定义请求头 在一个资源的加载进度停止之后被触发 arrayBuffer 异步 二进制数据缓存区
js 整数限制 浏览器文件大小限制 https://w3c.github.io/FileAPI/#dom-blob-arraybuffer https://developer.mozilla.org/ ...
- 按字节读取txt文件缓存区大小设置多少比较好?
读取 txt 文件常规写法有逐行读取和按照字节缓存读取,那么按照字节缓存读取时,设置缓存区多大比较好呢?百度了一下,没发现有说这个问题的,自测了一把,以事实说话. 常规读取方法如下: // 字节流读取 ...
- JAVA之旅(十七)——StringBuffer的概述,存储,删除,获取,修改,反转,将缓存区的数据存储到数组中,StringBuilder
JAVA之旅(十七)--StringBuffer的概述,存储,删除,获取,修改,反转,将缓存区的数据存储到数组中,StringBuilder 讲完String,我们来聊聊他的小兄弟 一.StringB ...
- IntelliJ IDEA修改Output输出缓存区大小【应对:too much output to process】
IntelliJ IDEA默认的Output输出缓存区大小只有1024KB,超过大小限制的就会被清除,而且还会显示[too much output to process],可通过如下配置界面进行修改O ...
- Java NIO------基础理论之缓存区
1.概述:NIO我的理解就是 New IO,是API1.4里提供的新的API,为所有的原始类型做缓存支持. NIO主要的核心组成部分: Buffer(缓存) Channels(通道) Selector ...
- 【MINA】缓存区ByteBuffer和IOBuffer你要了解的常用知识
mina中IOBuffer是Nio中ByteBuffer的衍生类,主要是解决Bytebuffer的两个不足 1.没有提供足够灵活的get/putXXX方法 2.它容量固定,难以写入可变长度的数据 特点 ...
- 如何计算Java对象所占内存的大小
[ 简单总结: 随便一个java项目,引入jar包: lucene-core-4.0.0.jar 如果是 maven项目,直接用如下依赖: <dependency> <groupId ...
随机推荐
- WPF编程,通过Double Animation动态旋转控件的一种方法。
原文:WPF编程,通过Double Animation动态旋转控件的一种方法. 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net/qq_43307934/art ...
- POJ 1459&&3436
两道比较基础的网络流题目,重点就是建图. 1458:题意就是给你一些东西它们的数据,其中一些是发电站,还有一些是用户的家里,其中还有一些是中转站.让你求最大的输送电量. 就是一道很基础的最大流题目,建 ...
- Ansible入门笔记(1)之工作架构和使用原理
目录 Ansible入门笔记(1) 1.Ansible特性 2.ansible架构解析 3.ansible主要组成部分 1)命令执行来源: 2)利用ansible实现管理的方式 3)Ansile-pl ...
- Java虚拟机笔记(五):JVM中对象的分代
为什么要分代 为什么需要把堆分代?不分代不能完成他所做的事情么?其实不分代完全可以,分代的唯一理由就是优化GC性能.你先想想,如果没有分代,那我们所有的对象都在一块,GC的时候我们要找到哪些对象没用, ...
- 爬虫利器_you-get
用Python做爬虫也很久了,今天分享一个轻巧的爬虫库:you-get you-get 是用 Python3写成的视频,图片,音频下载工具,堪称盗链,爬虫神器.其支持的网站,都是直接破解其算法,直接算 ...
- gulp.src()内部实现探究
写在前面 本来是想写个如何编写gulp插件的科普文的,突然探究欲又发作了,于是就有了这篇东西...翻了下源码看了下gulp.src()的实现,不禁由衷感慨:肿么这么复杂... 进入正题 首先我们看下g ...
- 记录一次Docker For Windows10镜像加速器配置
1.访问https://www.daocloud.io 注册账号 2.访问资源->加速器,或者直接访问网址https://www.daocloud.io/mirror,页面中间有加速配置,例如我 ...
- docker-compose编排
创建并启动容器 docker-compose up -d 备注: -d 后台启动并运行容器 前提是你在执行该命令的时候已经编写好了docker-compose.yml文件,在这个文件的当前目录执行上述 ...
- float和position的使用
http://blog.csdn.net/yaodebian/article/details/58621183
- VMware10 安装centos6.7 设置NAT模式固定ip
https://www.cnblogs.com/yychnbt/p/5173761.html