ByteBuf 内部结构设计
作者:互联网
一、首先介绍下 ReferenceCounted 接口
public interface ReferenceCounted {
/**
* 返回对象的引用数量,如果返回0,表示这个对象已经被释放
*/
int refCnt();
/**
* 引用计数加 1
*/
ReferenceCounted retain();
/**
* 引用计数加 increment
*/
ReferenceCounted retain(int increment);
/**
* 引用计数减 1,如果引用计数为0,则会释放这个对象
*
* @return 当且仅当引用计数变为0,并且这个对象已经被释放时返回true
*/
boolean release();
/**
* 引用计数减 decrement,如果引用计数为0,则会释放这个对象
* @return 当且仅当引用计数变为0,并且这个对象已经被释放时返回true
*/
boolean release(int decrement);
}
二、ByteBuf介绍
1、ByteBuf实现了ReferenceCounted接口,ByteBuf提供随机和顺序两种方式读取一个或者多个字节序列。
(1)Random Access Indexing
ByteBuf提供类似于原始数组的方式,起始索引是0,结束索引是capacity-1。
(2)Sequential Access Indexing
ByteBuf 提供两个指针来支持顺序读和顺序写操作。用readIndex来支持读操作,writeIndex来支持写操作。下图展示readIndex 和 writeIndex对ByteBuf进行分段
discardable bytes
这部分表示已经读过的区域,初始为0,最大值为writeIndex,执行读操作时这部分内容会相应的增加。可以通过调用 discardReadBytes 方法来回收这部分区域,达到获取更多writeable byte空间的效果
执行discardReadBytes之前如下图
执行discardReadBytes之后如下图
readable bytes
内容实际存储区域。执行以start或者skip开始的方法时,如果没有足够的内容供读取,会抛出 IndexOutOfBoundsException 异常
writeable bytes
可写区间
(3)Clearing the buffer index
可以调用clear方法来把readIndex 和 writeIndex的值重置为0,但是clear方法不会清空内容。
ByteBuf顺序读和顺序写、随机读和随机写的API都比较简单,此处不介绍。介绍下 ByteBuf 与 java nio 原生 ByteBuffer 转换
/**
* Returns the maximum number of NIO {@link ByteBuffer}s that consist this buffer. Note that {@link #nioBuffers()}
* or {@link #nioBuffers(int, int)} might return a less number of {@link ByteBuffer}s.
*
* @return {@code -1} if this buffer has no underlying {@link ByteBuffer}.
* the number of the underlying {@link ByteBuffer}s if this buffer has at least one underlying
* {@link ByteBuffer}. Note that this method does not return {@code 0} to avoid confusion.
*
* @see #nioBuffer()
* @see #nioBuffer(int, int)
* @see #nioBuffers()
* @see #nioBuffers(int, int)
*/
public abstract int nioBufferCount();
/**
* Exposes this buffer's readable bytes as an NIO {@link ByteBuffer}. The returned buffer
* shares the content with this buffer, while changing the position and limit of the returned
* NIO buffer does not affect the indexes and marks of this buffer. This method is identical
* to {@code buf.nioBuffer(buf.readerIndex(), buf.readableBytes())}. This method does not
* modify {@code readerIndex} or {@code writerIndex} of this buffer. Please note that the
* returned NIO buffer will not see the changes of this buffer if this buffer is a dynamic
* buffer and it adjusted its capacity.
*
* @throws UnsupportedOperationException
* if this buffer cannot create a {@link ByteBuffer} that shares the content with itself
*
* @see #nioBufferCount()
* @see #nioBuffers()
* @see #nioBuffers(int, int)
*/
public abstract ByteBuffer nioBuffer();
/**
* Exposes this buffer's sub-region as an NIO {@link ByteBuffer}. The returned buffer
* shares the content with this buffer, while changing the position and limit of the returned
* NIO buffer does not affect the indexes and marks of this buffer. This method does not
* modify {@code readerIndex} or {@code writerIndex} of this buffer. Please note that the
* returned NIO buffer will not see the changes of this buffer if this buffer is a dynamic
* buffer and it adjusted its capacity.
*
* @throws UnsupportedOperationException
* if this buffer cannot create a {@link ByteBuffer} that shares the content with itself
*
* @see #nioBufferCount()
* @see #nioBuffers()
* @see #nioBuffers(int, int)
*/
public abstract ByteBuffer nioBuffer(int index, int length);
/**
* Internal use only: Exposes the internal NIO buffer.
*/
public abstract ByteBuffer internalNioBuffer(int index, int length);
/**
* Exposes this buffer's readable bytes as an NIO {@link ByteBuffer}'s. The returned buffer
* shares the content with this buffer, while changing the position and limit of the returned
* NIO buffer does not affect the indexes and marks of this buffer. This method does not
* modify {@code readerIndex} or {@code writerIndex} of this buffer. Please note that the
* returned NIO buffer will not see the changes of this buffer if this buffer is a dynamic
* buffer and it adjusted its capacity.
*
*
* @throws UnsupportedOperationException
* if this buffer cannot create a {@link ByteBuffer} that shares the content with itself
*
* @see #nioBufferCount()
* @see #nioBuffer()
* @see #nioBuffer(int, int)
*/
public abstract ByteBuffer[] nioBuffers();
/**
* Exposes this buffer's bytes as an NIO {@link ByteBuffer}'s for the specified index and length
* The returned buffer shares the content with this buffer, while changing the position and limit
* of the returned NIO buffer does not affect the indexes and marks of this buffer. This method does
* not modify {@code readerIndex} or {@code writerIndex} of this buffer. Please note that the
* returned NIO buffer will not see the changes of this buffer if this buffer is a dynamic
* buffer and it adjusted its capacity.
*
* @throws UnsupportedOperationException
* if this buffer cannot create a {@link ByteBuffer} that shares the content with itself
*
* @see #nioBufferCount()
* @see #nioBuffer()
* @see #nioBuffer(int, int)
*/
public abstract ByteBuffer[] nioBuffers(int index, int length);
ByteBuf中不存在 java.nio.ByteBuffer的 allocateDirect(int capacity) 等方法。原因是Netty 对 ByteBuf 的创建单独抽象成一个体系 ByteBufAllocator,包括了直接内存、堆内存,池化的 ByteBuf,后续不断学习,不断补充。
标签:ByteBuf,buffer,see,int,内部结构,link,ByteBuffer,设计,NIO 来源: https://blog.csdn.net/ycb1914845451/article/details/110942860