Netty学习笔记之ByteBuf概览

一、ByteBuf

下图是ByteBuf的继承体系:

1、分类

1)从内存分配角度看,可分为两种:

(1)堆内存字节缓冲区:如上图中带有Heap的类,它们的特点是直接在堆中分配内存,分配和回收快,但缺点是在网络通信读写中,需额外做一次内存分配,

(2)直接内存缓冲区:使用直接内存进行内存分配,如上图中带有Direct的类,它们的特点是分配回收较慢,但网络通信中不需要进行额外的内存分配,类似于linux中的sendfile系统调用,它直接将内核缓冲区的数据复制到Channel中,不再经过用户缓冲区,因为少了一次复制,性能有所提升。

在实际使用中的最佳实践是在I/O通信线程的读写缓冲区使用直接内存缓冲区,后端业务消息的编解码使用堆内存缓冲区。

2)从内存回收角度看,可分为两类:

(1)基于对象池的ByteBuf:如继承体系中带有Pool的类,它们的内存管理基于对象池,它们自己维护了一个内存池,可提升使用效率。

(2)普通ByteBuf

基于对象池的ByteBuf使用时需要更加谨慎。

2ByteBuf简介

1ByteBufByteBuffer的比较

ByteBuf是对NIO中ByteBuffer的封装,为什么不使用原始的ByteBuffer呢?究其原因,ByteBuffer有以下不足:

(1):长度固定,一旦分配完成,则容量不能动态扩展或收缩;

(2):读写后不方便,因为每次都需要调用flip()等函数处理;

(3):API功能有限,一些高级和实用特性不支持。

2ByteBuf使用

创建ByteBuf的官方推荐方法是使用Unpool来创建,如:

ByteBuf buf = Unpooled.buffer(20);

        类似于ByteBuffer,ByteBuf中也有读写索引等概念,不同在于ByteBuffer使用一个位置指针处理读写操作,而ByteBuffer使用两个位置指针分别对读写进行操作,下图是ByteBuf的读写索引构造:

        其中readerIndex标识读取索引,writerIndex标识写索引,capacity为容量,即readerIndex到writerIndex部分是可读部分,writerIndex到capacity部分是可写部分。

        discardable bytes部分是可重用部分,这时我们可调用相应的api重用该部分内存来增加可写内存,如调用discardReadBytes()方法则会将writerIndex置为writerIndex – readerIndex,readerIndex置为0,同时发生数据的复制,即将原来可读的内容向前移动,所以频繁调用该函数将导致性能的下降。下图是调用discardReadBytes前后的对比图:

 

        一种更好的方法是调用clear()函数,这样不会导致内存的移动,它仅仅是移动了位置指针,不过会导致可读内容的晴空,下图是调用clear函数前后的情况:

       ByteBuf中也同样支持ByteBuffer中的mark和reset操作,不过更加丰富,它支持以下四个函数:

1markReaderIndex

2markWriterIndex

3resetReaderIndex

4resetWriterIndex

 

        ByteBuf中有Derived buffer的概念,ByteBuf提供了接口用于实现ByteBuf的复制,如以下方法:

(1)duplicate:返回当前ByteBuf的复制对象,但返回的ByteBuf对象与原始的ByteBuf共享缓冲区内容,即更改返回后ByteBuf的内容同样也会更改原始的ByteBuf中的内容,返回后的ByteBuf会维护自己独立的读写索引;

(2)copy:复制一个新的ByteBuf,与duplicate不同的是,返回后的ByteBuf在内容上是独立的。还有copy(int index, int length),从字面上也很好理解;

(3)slice:返回当前ByteBuf的可读子缓冲区,起始位置从readerIndex到writerIndex,返回后的ByteBuf与原ByteBuf共享内容,但读写索引地理维护。

 

        ByteBuf还可转换成标准的ByteBuffer,主要使用两个方法:

nioBuffer():将当前ByteBuf的可读缓冲区转换成ByteBuffer,但两者共享同一缓冲区内容。

nioBuffer(int index, int length):将当前ByteBufindex开始长度为length的缓冲区转换成ByteBuffer

 

        ByteBuf支持一系列的随机读写操作,它们是一系列set和get操作,具体见API。

转载于:https://my.oschina.net/u/1015154/blog/811317

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值