Netty实战第五章主要讲Netty封装的数据容器:ByteBuf(java中ByteBuffer的替代品,在网络中传输主要通过字节进行传输)。
Netty中主要通过abstract class ByteBuf、interface ByteBufHolder进行操作。
Netty中ByteBuf的主要优点:读写使用不同的索引(readIndex、writeIndex)、容量支持按需增长等。
ByteBuf主要的内存使用模式:
堆缓冲区,在ByteBuf内部通过byte[] 数组存放数据,数组内存分配在JVM中为堆,GC的主要作用区域也是堆:
/*
* 堆缓存,主要通过数组的形式表现。
*/
public static void heapBuff(){
ByteBuf buff = buf;
if(buff.hasArray()){// 判断byteBuff是否有一个支撑数组,数组分配内存在堆上。
byte[] array = buff.array();
int offset = buff.arrayOffset() + buff.readerIndex();
int length = buff.readableBytes();//获得可读的字节长度
handlerArray(array, offset, length);// 字节操作ByteBuf中的数组。
}
}
直接缓冲区:
通过JVM的堆缓冲区,在进行网络通信的时候,必须要将JVM中缓冲堆上的信息复制到内存的直接缓冲区,以便进行网络通信操作,所以直接使用ByteBuf的直接缓冲区会有一定优势。
/*
* 直接缓冲区
*/
public static void directBuff(){
ByteBuf buff = buf;
if (! buff.hasArray()){// 如果不是堆,则为直接缓存,分配一个大小合适的字节数组。
int length = buff.readableBytes();
byte[] arr = new byte[length];
buff.getBytes(buff.readerIndex(), arr);
handlerArray(arr , 0 , length);
}
}
混合缓冲区:
/*
* 使用compositeBuff作为缓冲区。
*/
public static void compositeBuffer(){
CompositeByteBuf buff = Unpooled.compositeBuffer();// 创建一个组合的缓冲区。
ByteBuf HeadBuff = buf;
ByteBuf BodyBuff = buf;
buff.addComponents(HeadBuff , BodyBuff);// 混合缓冲区
buff.removeComponent(0); // 移除index = 0的组成部分,即为HeadBuff。
for(ByteBuf buffComponent : buff){
System.out.println(buffComponent.toString());
}
}