Mina 组件介绍之 IoBuffer
在Java NIO 中,ByteBuffer通常作为通信中传递消息的载体。而在Mina中,采用了IoBuffer代替ByteBuffer。Mina给出了不用ByteBuffer的两个主要理由:
1. ByteBuffer未提供一些常用到的get/set方法,如:fill, get/putString, get/putAsciiInt
这里附上,fill方法在AbstractIoBuffer中的实现,可以看到程序分别采用Long,Int,Short,byte对指定size的byte内容进行了快速填充,而不是采用for循环,是个有趣的技巧。
public IoBuffer fill(byte value, int size) {
autoExpand(size);
int q = size >>> 3;
int r = size & 7; if (q > 0) {
int intValue = value | value << 8 | value << 16 | value << 24;
long longValue = intValue;
longValue <<= 32;
longValue |= intValue; for (int i = q; i > 0; i--) {
putLong(longValue);
}
} q = r >>> 2;
r = r & 3; if (q > 0) {
int intValue = value | value << 8 | value << 16 | value << 24;
putInt(intValue);
} q = r >> 1;
r = r & 1; if (q > 0) {
short shortValue = (short) (value | value << 8);
putShort(shortValue);
} if (r > 0) {
put(value);
} return this;
}2. ByteBuffer一旦分配,容量固定,不易扩展。
在Mina的实现中,IoBuffer的扩展是通过重新分配一块新的更大的ByteBuffer,并把旧的ByteBuffer拷贝到新的当中实现的,这种实现的问题显而易见,可能导致频繁分配内存,生成内存碎片。另外,在用户使用DirectBuffer时,频繁的内存分配和释放(ByteBuffer.clear())可能导致内存不能及时回收,从而导致内存泄漏。关于IoBuffer自动扩展的问题在Mina的官方网站上也有提及:
This will change in MINA 3. The main reason why MINA has its own wrapper on top of nio ByteBuffer is to have extensible buffers. This was a very bad decision. Buffers are just buffers : a temporary place to store temporary data, before it is used. Many other solutions exist, like defining a wrapper which relies on a list of NIO ByteBuffers, instead of copying the existing buffer to a bigger one just because we want to extend the buffer capacity.
It might also be more comfortable to use an InputStream instead of a byte buffer all along the filters, as it does not imply anything about the nature of the stored data : it can be a byte array, strings, messages... Last, not least, the current implementation defeat one of the target : zero-copy strategy (ie, once we have read the data from the socket, we want to avoid a copy being done later). As we use extensible byte buffers, we will most certainly copy those data if we have to manage big messages. Assuming that the MINA ByteBuffer is just a wrapper on top of NIO ByteBuffer, this can be a real problem when using direct buffers.总结起来主要是:0. 实现自动扩展是错误的决定; 1. 可以有更好的实现方式,如ByteBuffer List; 2. 违反了zero-copy 原则; 3. 在用户使用Direct模式管理较大的Message存在内存泄漏的风险。
可见Mina对于ByteBuffer的包装IoBuffer是存在一定问题的,官方考虑放弃。但是Mina社区目前基本处于停滞状态。(最新的稳定版本时间还是2016年10月)
Mina 组件介绍之 IoBuffer的更多相关文章
- Mina 组件介绍之 IoAcceptor 与 IoConnector
在网络通信中,Socket通信的双方分为服务端与客户端,在Java NIO 的实现中采用Socket/ServerSocket, SocketChannel/ServerSocketChannel分别 ...
- Mina各组件介绍
Mina各组件介绍 上一篇文章已经系统的介绍了Mina的运行流程,Apache推出的Mina性能上很是高效,上章节我们知道内部有很多的类,各个类之间的依赖也是很多,他们之家都是相互依赖. 下面主要看看 ...
- 开源免费且稳定实用的.NET PDF打印组件itextSharp(.NET组件介绍之八)
在这个.NET组件的介绍系列中,受到了很多园友的支持,一些园友(如:数据之巅. [秦时明月]等等这些大神 )也给我提出了对应的建议,我正在努力去改正,有不足之处还望大家多多包涵.在传播一些简单的知识的 ...
- 免费开源的.NET多类型文件解压缩组件SharpZipLib(.NET组件介绍之七)
前面介绍了六种.NET组件,其中有一种组件是写文件的压缩和解压,现在介绍另一种文件的解压缩组件SharpZipLib.在这个组件介绍系列中,只为简单的介绍组件的背景和简单的应用,读者在阅读时可以结合官 ...
- 免费高效实用的.NET操作Excel组件NPOI(.NET组件介绍之六)
很多的软件项目几乎都包含着对文档的操作,前面已经介绍过两款操作文档的组件,现在介绍一款文档操作的组件NPOI. NPOI可以生成没有安装在您的服务器上的Microsoft Office套件的Excel ...
- 免费开源的DotNet任务调度组件Quartz.NET(.NET组件介绍之五)
很多的软件项目中都会使用到定时任务.定时轮询数据库同步,定时邮件通知等功能..NET Framework具有“内置”定时器功能,通过System.Timers.Timer类.在使用Timer类需要面对 ...
- 免费开源的DotNet二维码操作组件ThoughtWorks.QRCode(.NET组件介绍之四)
在生活中有一种东西几乎已经快要成为我们的另一个电子”身份证“,那就是二维码.无论是在软件开发的过程中,还是在普通用户的日常中,几乎都离不开二维码.二维码 (dimensional barcode) , ...
- 最好的.NET开源免费ZIP库DotNetZip(.NET组件介绍之三)
在项目开发中,除了对数据的展示更多的就是对文件的相关操作,例如文件的创建和删除,以及文件的压缩和解压.文件压缩的好处有很多,主要就是在文件传输的方面,文件压缩的好处就不需要赘述,因为无论是开发者,还是 ...
- 高效而稳定的企业级.NET Office 组件Spire(.NET组件介绍之二)
在项目开发中,尤其是企业的业务系统中,对文档的操作是非常多的,有时几乎给人一种错觉的是”这个系统似乎就是专门操作文档的“.毕竟现在的很多办公中大都是在PC端操作文档等软件,在这些庞大而繁重的业务中,单 ...
随机推荐
- js for in 遍历对象与数组
遍历对象 let obj = { q:'9', w:'5', e:'2', t:'7', c:'3' } //for in 遍历对象 key为对象的属性名称,遍历属性值时用[]操作符访问 //通过[] ...
- Linux自有服务
Linux自有服务 Linux自带的功能:运行模式.用户和用户组管理.网络配置.ssh服务 1.运行模式 Linux下的初始化进程:init,进程id为1 该进程的配置文件:/etc/inittab ...
- 关于datagridview中checkbox列在选中行的情况下无法操作值
这几天做项目的时候碰到了个小问题,在datagridview中实现对checkbox列的全选和反选功能.代码如下 //全选 if (dataGrid ...
- eclipse中手动设置library,选择编译工具方法
target=android-25sdk.buildtools=25.0.2 target=android-26android.library=falseandroid.library.referen ...
- geth访问公有链
同步以太坊,配置rpc地址 mkdir /opt/blockchain nohup geth --syncmode "fast" --cache=1024 --maxpeers 3 ...
- 国家与大洲对应关系json数据
[ { "continent_cname": "欧洲", "continent_name": "EU", "c ...
- day009-IO流
什么叫流?就是数据的流动.以内存为基准,分为输入input和输出output.输入也叫做读取数据,输出也叫写出数据. 分类 按数据的流向分: 输入流.输出流 按数据类型分: 字节流.字符流 1. ...
- 【Spring实战】—— 15 Spring JDBC模板使用
前一篇通过对传统的JDBC的使用操作,可以体会到使用的繁琐与复杂,套句话说,是用了20%作了真正的工作,80%作了重复的工作. 那么通过本篇,可以了解如下的内容: 1 如何配置数据源 2 如何在spr ...
- 收放卷及张力控制 PID调试技巧
1) 小 Kp( 0.01) , 大 Ti ( 20000ms) 2)逐渐增大Kp, 减小Ti ( 20000ms – 3000ms),避免发生震荡 3)观察I-out 是否在0附近 可能原因:卷径不 ...
- zt dup() 和 dup2()
dup() 和 dup2() 2011-10-07 11:06:31| 分类: Linux学习心得 |字号 订阅 dup和dup2都可用来复制一个现存的文件描述符,使两个文件描述符指向同一个fi ...