Netty学习笔记(七)ByteBuf分析
ByteBuf
java NIO 使用ByteBuffer作为字节容器,使用上过于复杂,为此netty使用ByteBuf来代替ByteBuffer。ByteBuf是一个抽象类,不能直接使用,它的子类有:
ByteBuf子类
它有两个重要的指针:readerIndex读指针,writerIndex写指针。在ByteBuf的0到readerIndex区间内不可读,在readerIndex到writerIndex区间内可读,在writerIndex到capacity容量区间内可写入。
另外ByteBuf还有个概念就是maxCapacity,即最大容量,当写数据的时候已经超过当前容量capacity的时候,就会扩容,扩容的最大值就是maxCapacity。
AbstractByteBuf
AbstractByteBuf抽象类继承ByteBuf,但它也是一个抽象类。除了ByteBuf中的那些属性外,它还有markedReaderIndex和markedWriterIndex属性,用以记录执行某些操作之前先保存原来的读写指针。另外,它有些方法还是抽象类的,需要其他类去继承和实现。
从ByteBuf继承关系的类图可以看出,继承了AbstractByteBuf的类很多都以Pooled和Unpooled命名的。AbstractByteBuf重写了readByte方法:
@Override
public byte readByte() {
checkReadableBytes0(1);
int i = readerIndex;
byte b = _getByte(i);
readerIndex = i + 1;
return b;
}
其中_getByte()在这里仍然是个抽象类,需要继承他的子类去实现,读操作结束后,读指针往后加1。
writeByte()方法实现如下:
@Override
public ByteBuf writeByte(int value) {
ensureAccessible();
ensureWritable0(1);
_setByte(writerIndex++, value);
return this;
}
_setByte()方法也是一个抽象类,需要子类去实现。
总结来说,AbstractByteBuf类也是一个“骨架”,并未实现最终的读写操作。
Pooled和Unpooled区别
AbstractByteBuf的众多子类中,有些以Pooled开头,意思是创建ByteBuf时的内存从预先创建好的一片内存中分配;以Unpooled开头,表示创建时候的内存是直接向操作系统中申请的内存。
Unsafe和非Unsafe的区别
类名中有Unsafe表示这个类实现的读写方法中是直接根据内存地址去直接读写内存的,而没有带上Unsafe表示这个类的读写没有直接去操作内存。
Heap和Direct的 区别
类名中有Heap的表示内存是在堆上进行分配的,受GC管理;而Direct表示内存不在堆上分配,不受GC管理。