Netty学习笔记之ByteBuf概览

1、ByteBuflinux

下图是ByteBuf的继承体系:后端

1、分类api

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。

相关文章
相关标签/搜索