1 Netty緩沖區——ByteBuf
Netty的ByteBuf是一個抽象類,是Netty管轄的內存,里面主要是一些byte數組的讀寫方法,與其說是抽象類,不如說它是一個接口,因為它里面幾乎全是抽象方法,下面是截取它的一部分方法:
ByteBuf有四個重要的實現類:PooledDirectByteBuf,PooledHeapByteBuf, UnpooledDirectByteBuf,UnpooledHeapByteBuf, 它們分別代表池化直接內存,池化堆內存,未池化直接內存,未池化堆內存。直接內存代表沒有數據從內核空間到用戶空間的復制,代表高效;池化代表高效的內存分配和釋放。
1.1 內存分配
四種內存分配:
// 未池化堆內存
ByteBuf heapByteBuf = Unpooled.buffer(10);
// 未池化直接內存
ByteBuf directByteBuf = Unpooled.directBuffer(10);
// 池化堆內存
PooledByteBufAllocator allocator = new PooledByteBufAllocator(false);
ByteBuf pHeapByteBuf = allocator.buffer();
// 池化直接內存
PooledByteBufAllocator allocator2 = new PooledByteBufAllocator(true);
ByteBuf pDirectByteBuf = allocator.buffer();
復合內存是把上述幾種內存復合成一個對象來操作的一種內存。
CompositeByteBuf compositeByteBuf = Unpooled.compositeBuffer();
compositeByteBuf.addComponents(heapByteBuf, directByteBuf, pHeapByteBuf, pDirectByteBuf);
1
2
1.2 內存讀寫操作
ByteBuf 有兩個游標,readerIndex指向已讀字節位,writerIndex指向已寫字節位。通常我們不會對同一個ByteBuf一邊讀一邊寫,因此可以理解為讀操作時只存在readerIndex一個游標,寫操作時只存在writerIndex一個游標。這兩個游標會隨着我們的讀寫操作自動變換位置,也可以手動強行把它們移動到指定位置。
讀示例:
// 讀取前判斷可讀狀態
if (heapByteBuf.isReadable()) {
// 計算可讀長度
int len = heapByteBuf.readableBytes();
// 可以直接讀出到ByteBuf中
ByteBuf read = heapByteBuf.readBytes(len/2);
// 也可讀出到指定byte數組
byte[] dis = new byte[len/2];
heapByteBuf.readBytes(dis);
}
寫示例:
// 寫前判斷可寫余量
if (heapByteBuf.isWritable()){
// XXX可以是byte[] 和 ByteBuf
heapByteBuf.writeBytes(XXX);
}
1.3 內存釋放
ByteBuf內存釋放: ByteBuf抽象類實現了ReferenceCounted接口,實現引用計數功能。引用計數為0時可以釋放:
directByteBuf.release();
1
netty在有些地方會自動釋放ByteBuf,在有些地方又不會,總結3.1.4的內容:只有未繼承SimpleChannelInboundHandler的響應ByteBuf需要手動在業務代碼中使用ReferenceCountUtil.release(byteBuf)釋放,其他情況,不論是否池化,不論請求還是響應,都由Netty自動釋放。
————————————————
版權聲明:本文為CSDN博主「舊城燈火」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/qq_32717909/article/details/91635714