netty4.0 关于buffer

NIO中的buffer很经典,但是也需要小心翼翼。比如,flip如果不用好,就可能出错。
netty中重新封装了buffer,于是ByteBuf出现了。

public interface ByteBuf extends ChannelBuf, Comparable<ByteBuf> {
public ByteBufAllocator alloc();
public byte[] array();
public int arrayOffset();
public int bytesBefore(byte);
public int bytesBefore(ByteBufIndexFinder);
public int bytesBefore(int, byte);
public int bytesBefore(int, ByteBufIndexFinder);
public int bytesBefore(int, int, byte);
public int bytesBefore(int, int, byteBufIndexFinder);
public int capacity();
public ByteBuf capacity(int);
public ByteBuf clear();
public int compareTo(ByteBuf);
public ByteBuf copy();
public ByteBuf copy(int, int);
public ByteBuf discardReadBytes();
public ByteBuf duplicate();
public ByteBuf ensureWritableBytes(int);
public ByteBuf ensureWritableBytes(int, boolean);
public boolean equals(Object);
...
}

实在是太多,不一一罗列。这里注意的是,readerIndex()和writerIndex()说明有两个指针,这样的话,在0和readerIndex()之间的数据就表示已经读过的,调用discardReadBytes()就可以删除这些数据,类似NIO中的compact
这样做的好处是减少不必要的拷贝。指针是个宝。
当然这里的ByteBuf也把ByteBuffer中该有的都不落下。同时看接口,ChannelBuf只是一个方法 type()返回表明是byte还是message数据。comparable大家都很熟悉了。

ByteBuf是个接口,她有两个子接口
CompositeByteBuf 和 UnsafeByteBuf
CompositeByteBuf 就是多个ByteBuf的组合。
UnsafeByteBuf则是增加了一些方法,可以操作NIO。
接下来有 AbstractByteBuf,ReplayingDecoderBuffer和SwappedByteBuf
当然这些都不怎么用,SwappedByteBuf直接把传入的ByteBuf的字节序弄反就是了。
ReplayingDecoderBuffer则是在terminate以后,才返回capacity,这样可以用于在接受数据时,如果数据接收齐全了,就使用terminate()函数。


在AbstractByteBuf的强大实现下,开始有很多的子类了。大家可以看看。
这里要说常用的。例如UnpooledHeapByteBuf和UnpooledDirectByteBuf
这两个类基本上就是ByteBuf的实现类,工具类UnpooledByteBufAllocator正是通过返回他们得到想要的ByteBuf实例。文档上建议我们使用Unpooled工具类来创建这些ByteBuf,例如 directBuffer() 或者 wrappedBuffer(byte[]),wrappedBuffer(ByteBuffer) 等。

UnpooledDirectByteBuf很有意思,请看

private static final Field CLEANER_FIELD;

static {
ByteBuffer direct = ByteBuffer.allocateDirect(1);
Field cleanerField;
try {
cleanerField = direct.getClass().getDeclaredField("cleaner");
cleanerField.setAccessible(true);
Cleaner cleaner = (Cleaner) cleanerField.get(direct);
cleaner.clean();
} catch (Throwable t) {
cleanerField = null;
}
CLEANER_FIELD = cleanerField;
}


这里正是NIO中一个头疼的问题,就是direct memory的回收。这里给出一个解决办法。通常我们都是使用了System.gc()去建议JVM回收。
下面是使用。

private static void freeDirect(ByteBuffer buffer) {
if (CLEANER_FIELD == null) {
// Doomed to wait for GC.
return;
}

Cleaner cleaner;
try {
cleaner = (Cleaner) CLEANER_FIELD.get(buffer);
cleaner.clean();
} catch (Throwable t) {
// Nothing we can do here.
}
}



netty4.0 buffer,使用了读写指针直接对byte进行封装。并没有在NIO的buffer上再次封装,对于NIO buffer,则是直接使用byte array包装。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值