Netty-源码分析ByteBuf-slice和retainedSlice使用细节
slice() = slice(buf.readerIndex(), buf.readableBytes())
源码片段,返回原始ByteBuf可读字节的一部分, 修改返回的缓冲区或此缓冲区的内容会影响彼此的内容,他们维护单独的index和makers,此方法不会修改原始缓冲区的readerIndex或writerIndex。
@Override
public ByteBuf slice() {
return slice(readerIndex, readableBytes());
}
@Override
public ByteBuf slice(int index, int length) {
ensureAccessible();
return new UnpooledSlicedByteBuf(this, index, length);
}
boolean release0() {
return unwrap().release();
}
public static void main(String[] args) throws Exception {
PooledByteBufAllocator allocator = PooledByteBufAllocator.DEFAULT;
ByteBuf original = allocator.directBuffer(32);
original.writeByte(1);
original.writeByte(2);
original.writeByte(3);
//相当于original.slice(original.readerIndex(), original.readableBytes());
ByteBuf sub = original.slice();
//新缓冲区修改值后互相影响
sub.setByte(0, 10);
System.out.println("sub.readByte = " + sub.readByte());
System.out.println("original.readByte = " + original.readByte());
//原始缓冲区在读一次
System.out.println("original.readByte = " + original.readByte());
//Index互不影响
System.out.println("sub.readerIndex = " + sub.readerIndex());
System.out.println("original.readerIndex = " + original.readerIndex());
//必须释放
original.release();
}
与slice一模一样,只是调用了retain,在使用完毕后需要多释放一次。
@Override
public ByteBuf retainedSlice() {
return slice().retain();
}
@Override
public final ByteBuf retain() {
return retain0();
}
ByteBuf retain0() {
unwrap().retain();
return this;
}
在使用完毕后,必须要释放俩次。
public static void main(String[] args) throws Exception {
PooledByteBufAllocator allocator = PooledByteBufAllocator.DEFAULT;
ByteBuf original = allocator.directBuffer(32);
original.writeByte(1);
original.writeByte(2);
original.writeByte(3);
ByteBuf sub = original.retainedSlice();
sub.release();
original.release();
System.out.println("sub.refCnt = " + sub.refCnt());
System.out.println("original.refCnt = " + original.refCnt());
AbstractPooledDerivedByteBuf源码分析
final <U extends AbstractPooledDerivedByteBuf> U init(
AbstractByteBuf unwrapped, ByteBuf wrapped, int readerIndex, int writerIndex, int maxCapacity) {
//原始缓冲区计数器++
wrapped.retain(); // Retain up front to ensure the parent is accessible before doing more work.
parent = wrapped;
rootParent = unwrapped;
try {
maxCapacity(maxCapacity);
setIndex0(readerIndex, writerIndex); // It is assumed the bounds checking is done by the caller.
resetRefCnt();
@Override
protected final void deallocate() {
// We need to first store a reference to the parent before recycle this instance. This is needed as
// otherwise it is possible that the same AbstractPooledDerivedByteBuf is again obtained and init(...) is
// called before we actually have a chance to call release(). This leads to call release() on the wrong parent.
ByteBuf parent = this.parent;
recyclerHandle.recycle(this);
//子缓冲区释放会 减少原始缓冲区计数器
parent.release();
}
来源:CSDN
作者:温故而知新666
链接:https://blog.csdn.net/nimasike/article/details/103461422