目录

ByteBuf的结构

常见API

read

write

get、set

mark、reset

ByteBuf的分类

继承体系图

AbstractByteBuf

Pooled与Unpooled

Unsafe与非Unsafe

Heap与Direct


ByteBuf是Netty底层直接与数据打交道的一层抽象。ByteBuf作为数据流的载体,提供了一些列简单易用的API来操作底层数据流。

ByteBuf的结构

discardable bytes:0 <= readerIndex(无效部分)

readable bytes:readerIndex <= writerIndex(可读部分)

writable bytes:writerIndex <= capacity(可写部分或空闲部分)


常见API

read

常见的read相关API有readByte、readBytes、readInt、readLong、readChar等,读取的过程是从readerIndex开始向前读取类型对应的字节长度,读取完成后readerIndex也会向前移动相应的长度。

write

常见的write相关API有writeByte、writeBytes、writeInt、writeLong、writeChar等,写的过程与读过程相似,从writerIndex开始向前写入数据,对应的writerIndex也会移动到写完的位置。

get、set

与read、write相对应的还有get、set相关的API,这两种API在读数据或写数据时,都需要提供index参数,并且不会移动readerIndex或writerIndex。

mark、reset

我们知道read与write相关的API在执行完成后会移动index指针,而通过mark和reset可以实现index位置还原,例如markReaderIndex与resetReaderIndex可以还原readerIndex,markWriterIndex与resetWriterIndex可以还原writerIndex。


ByteBuf的分类

继承体系图


AbstractByteBuf

AbstractByteBuf是ByteBuf的骨架实现,里面定义了各种通用变量与API实现,而以下划线开头的抽象类则交给具体子类实现。

public abstract class AbstractByteBuf extends ByteBuf {
    ......
    // 保存各种指针的值
    int readerIndex;
    int writerIndex;
    private int markedReaderIndex;
    private int markedWriterIndex;
    private int maxCapacity;

    // 各种API的实现
    @Override
    public byte readByte() {
        checkReadableBytes0(1);
        int i = readerIndex;
        // 下划线开头的方法都是抽象方法,由具体子类实现
        byte b = _getByte(i);
        // 位置指针移动
        readerIndex = i + 1;
        return b;
    }

    @Override
    public byte getByte(int index) {
        checkIndex(index);
        return _getByte(index);
    }

    protected abstract byte _getByte(int index);

    @Override
    public ByteBuf writeByte(int value) {
        ensureAccessible();
        ensureWritable0(1);
        _setByte(writerIndex++, value);
        return this;
    }

    @Override
    public ByteBuf setByte(int index, int value) {
        checkIndex(index);
        _setByte(index, value);
        return this;
    }

    protected abstract void _setByte(int index, int value);
    ......
}

Pooled与Unpooled

Pooled(池化)方式每次分配内存时都会从系统预先分配好的一段内存中来取。

Unpooled(非池化)方式每次分配内存时都会调用系统API向操作系统申请内存创建ByteBuf。


Unsafe与非Unsafe

Unsafe会先计算数据的内存地址+偏移量,通过unsafe对象的native API来操作数据。

非Unsafe不依赖JDK的unsafe对象,它是通过数组+下标方式来获取数据,或者是通过JDK 底层的ByteBuffer API进行读写,一般而言unsafe方式效率更高一些。


Heap与Direct

Heap代表堆上内存分配,会被GC管理。

Direct代表堆外内存分配,调用JDK底层API进行分配系统内存,效率更高,但不受GC控制,需要手动释放内存。

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐