Netty的ByteBuf缓冲区实现地比Java本身的ByteBuffer更加灵活,方便。它的类结构也比较复杂,这里只说ByteBuf核心的几个要点。
1. 最重要的是要理解为什么要ByteBuf这个组件。主要还是因为基于select / poll / epoll这种IO多路复用技术的NIO是非阻塞同步IO的模型,由于是同步IO,需要用户线程自己来处理IO的读写,由于是非阻塞的,每次调用read, write读写的字节数是不确定的,所以非阻塞同步IO必须有缓冲区这个组件来保存每次读写的中间状态,通过缓冲区来确定是否读写完成。更多内容请参考http://blog.csdn.net/iter_zc/article/details/39291647
2. ByteBuf不是对ByteBuffer的封装,而是重新实现了一个缓冲区。ByteBuffer只使用了一个position指针来记录当前的读写位置,ByteBuf使用了两个指针readerIndex, writerIndex分别来记录当前的读写位置,使用起来更加简单和方便。
3. ByteBuffer是一个固定长度的缓冲区,当put方法要写的数据大于可写的容量时会抛出异常。ByteBuf改进了这个设计,支持自动扩容。每次put之前会检查是否可以完全写入,如果不能,就会自动扩展ByteBuf的容量,保证put方法不会抛出异常。
public ByteBuf writeInt(int value) { ensureWritable(4); _setInt(writerIndex, value); writerIndex += 4; return this;} public ByteBuf ensureWritable(int minWritableBytes) { if (minWritableBytes < 0) { throw new IllegalArgumentException(String.format( "minWritableBytes: %d (expected: >= 0)", minWritableBytes)); } if (minWritableBytes <= writableBytes()) { return this; } if (minWritableBytes > maxCapacity - writerIndex) { throw new IndexOutOfBoundsException(String.format( "writerIndex(%d) + minWritableBytes(%d) exceeds maxCapacity(%d): %s", writerIndex, minWritableBytes, maxCapacity, this)); } // Normalize the current capacity to the power of 2. int newCapacity = calculateNewCapacity(writerIndex + minWritableBytes); // Adjust to the new capacity. capacity(newCapacity); return this;}//UnpooledHeapByteBuf的capacity方法来自动扩容public ByteBuf capacity(int newCapacity) { ensureAccessible(); if (newCapacity < 0 || newCapacity > maxCapacity()) { throw new IllegalArgumentException("newCapacity: " + newCapacity); } int oldCapacity = array.length; if (newCapacity > oldCapacity) { byte[] newArray = new byte[newCapacity]; System.arraycopy(array, 0, newArray, 0, array.length); setArray(newArray); } else if (newCapacity < oldCapacity) { byte[] newArray = new byte[newCapacity]; int readerIndex = readerIndex(); if (readerIndex < newCapacity) { int writerIndex = writerIndex(); if (writerIndex > newCapacity) { writerIndex(writerIndex = newCapacity); } System.arraycopy(array, readerIndex, newArray, readerIndex, writerIndex - readerIndex); } else { setIndex(newCapacity, newCapacity); } setArray(newArray); } return this;}private void setArray(byte[] initialArray) { array = initialArray; tmpNioBuf = null;}
4. 和ByteBuffer一样,ByteBuf也支持堆内缓冲区和堆外直接缓冲区,根据经验来说,底层IO处理线程的缓冲区使用堆外直接缓冲区,减少一次IO复制。业务消息的编解码使用堆内缓冲区,分配效率更高,而且不涉及到内核缓冲区的复制问题。
5. ByteBuf的堆内缓冲区又分为内存池缓冲区PooledByteBuf和普通内存缓冲区UnpooledHeapByteBuf。PooledByteBuf采用二叉树来实现一个内存池,集中管理内存的分配和释放,不用每次使用都新建一个缓冲区对象。UnpooledHeapByteBuf每次都会新建一个缓冲区对象。在高并发的情况下推荐使用PooledByteBuf,可以节约内存的分配。在性能能够保证的情况下,可以使用UnpooledHeapByteBuf,实现比较简单。
相关推荐
对于 Netty ByteBuf 的零拷贝(Zero Copy) 的理解1
类似于Netty ByteBuf的ByteBuf的Rust实现
netty通信时经常和底层数据交互,C语言和java的数据类型和范围不同,通信时需要转化或兼容,附件为字节码、进制常用的转换类。
将Netty ByteBuf的相关类,进行梳理总结、源码分析,通过思维导图的注释看源码!
再根据本人实际学习体验总结而成。本部分内容可能不那么全面,但是我尽量挑选Netty中我认为比较重要的部分做讲解。
6.数据传输载体ByteBuf介绍 12 7.客户端与服务端通信协议编解码 14 8.实战:Netty实现客户端登录 15 9.实战:实现客户端与服务端收发消息 16 10.Pipeline与ChannelHandler 17 11.实战:构建客户端与服务端 Pipeline 18 ...
5_Netty执行流程分析与重要组件介绍 6_Netty回调与Channel执行流程分析 7_Netty的Socket编程详解 8_Netty多客户端连接与通信 9_Netty读写检测机制与长连接要素 10_Netty对WebSocket的支援 11_Netty实现服务器端与...
第5讲:Netty执行流程分析与重要组件介绍 第6讲:Netty回调与Channel执行流程分析 第7讲:Netty的Socket编程详解 第8讲:Netty多客户端连接与通信 第9讲:Netty读写检测机制与长连接要素 第10讲:Netty对...
76_Netty项目开发过程中常见且重要事项分析 77_Java NIO Buffer总结回顾与难点拓展 78_Netty数据容器ByteBuf底层数据结构深度剖析 79_Netty的ByteBuf底层实现大揭秘 80_Netty复合缓冲区详解与3种缓冲区适用场景分析 ...
第15章 ByteBuf 和相关辅助类 第16章 Channel 和Unsafe 第17章 ChannelPipeline 和ChannelHandler 第18章 EvenLoop 和EventLoopGroup 第19章 Future 和Promise 第20章 Netty 架构解析 第21章j ava多线程编程在netty...
第15 章 ByteBuf 和相关辅助类...... 288 第16 章 Channel 和Unsafe ...... 338 第17 章 ChannelPipeline 和ChannelHandler...... 388 第18 章 EventLoop 和EventLoopGroup...... 419 ...
Netty是一个异步事件驱动的网络应用...只需要理解并熟练运用ByteBuf、Channel、Pipeline、Event模型等相关技术,就可以进行Netty的开发。同时,Netty对事件的处理也非常灵活,支持用户自定义各种类型的ChannelHandler。
Netty框架中LineBasedFrameDecoder分隔符解码器解决考虑TCP的粘包与拆包问题。依次编译bytebuf中的可读字符,判断看是否有“\n”或者“\r\n”,如果有,就以此位置为结束位置,从可读索引到结束位置区间的字节就组成...
Netty是一个异步事件驱动的网络应用...只需要理解并熟练运用ByteBuf、Channel、Pipeline、Event模型等相关技术,就可以进行Netty的开发。同时,Netty对事件的处理也非常灵活,支持用户自定义各种类型的ChannelHandler。
第5章 ByteBuf 第6章 ChannelHandler和ChannelPipeline 第7章 EventLoop和线程模型 第8章 引导 第9章 单元测试 第二部分 编解码器 第10章 编解码器框架 第11章 预置的ChannelHandler和编解码器 第三部分 ...
UdpServerSocketChannel: ...import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import io.netty.channel.ChannelFactory; import io.netty.channel.Ch
首先写一个测试方法,直接向ByteBuf写入中国万岁!,然后如果是堆内存直接打印即可。源码如下: @Test public void testHeapBuffer2() { //取得堆内存 (但是默认是 directByDefault=true) By
Netty中频道的分类 NioServerSocketChannel服务端的Channel,在服务启动的时候创建,用于接收新连接 NioSocketChannel客服端Channel,在新连接进入时创建,并负责监听数据读写 不安全,用于实现两个频道临时的协议...
org.apache.mina.core.buffer.IoBuffer mina core 包
Netty 4.x写一个分区服务器 写个特定服务器 世上最简单的协议不是而是DISCARD(替代)。这个协议将会丢掉任何收到的数据,而不响应。... (( ByteBuf ) msg) . release(); } @Override public voi