ByteBufAllocator接口的继承图如下:
它提供了一系列接口给用户调用, 包括生成各种ByteBuf 的操作,例如 ioBuffer(), heapBuffer(), directBuffer(), compositeBuffer()等等,并且提供了一个默认工厂ByteBufAllocator DEFAULT = ByteBufUtil.DEFAULT_ALLOCATOR; 在ByteBufUtil工具类里定义了一个默认工厂, 默认工厂的具体类型需要由具体实现的子类确定,默认情况下, 根据当前应用所在的平台, 判断需要使用池化工厂还是非池化工厂。
AbstractByteBufAllocator
AbstractByteBufAllocator抽象类首先实现了ByteBufAllocator接口,这是对工厂实现的一层抽象, 设计巧妙。
内存泄漏检测功能
首先抽象层实现了内存泄漏检测功能, 原因是对于DirectBuf,其内存不受VM垃圾回收控制只有在调用release导致计数为0时才会主动释放内存,而PooledByteBuf只有在release后才能被回收到池中以循环利用。netty定义了4种层级的内存泄漏检测,如下所示:
|
|
默认的监测等级是SIMPLE;所以启用内存泄露检测之后,内存得到的ByteBuf对象都是经过toLeakAwareBuffer()方法封装的,该方法作用就是对ByteBuf对象进行引用计数,使用SimpleLeakAwareByteBuf或者AdvancedLeakAwareByteBuf来包装ByteBuf。首先通过toLeakAwareBuffer(ByteBuf )方法根据不同的等级调用会AbstractByteBuf.leakDetector.track(buf),它的目的在于返回一个DefaultResourceLeak对象,用于构建SimpleLeakAwareByteBuf或者AdvancedLeakAwareByteBuf。DefaultResourceLeak继承了虚引用WeakReference,实现了ResourceLeakTracker和ResourceLeak接口。我们看一下代码部分:
|
|
PooledByteBufAllocator
heap内存的分配
|
|
direct内存的分配
|
|
UnpooledByteBufAllocator
heap内存的分配
|
|
UnpooledHeapByteBuf和UnpooledUnsafeHeapByteBuf存储的时候,都是通过一个array。但是_getByte(array,index)的时候,UnpooledUnsafeHeapByteBuf底层是直接操作array:
|
|
而 UnpooledHeapByteBuf是通过UNSAFE操作这个数组:
|
|
UnpooledHeapByteBuf和UnpooledUnsafeHeapByteBuf存储的时候,都是通过一个array。但是_getByte(array,index)的时候,UnpooledHeapByteBuf底层是直接操作array;而 UnpooledUnsafeHeapByteBuf是通过UNSAFE操作这个数组。
direct内存的分配
|
|
UnpooledDirectByteBuf和UnpooledUnsafeDirectByteBuf存储的时候,都通过了一个buffer存储(而且UnpooledUnsafeDirectByteBuf还会计算这个buffer在内存的地址memoryAddress,以后通过操作这个memoryAddress+index操作buffer)。_getByte(index)的时候UnpooledDirectByteBuf通过操作这个buffer操作数据;
|
|
而UnpooledUnsafeDirectByteBuf通过操作unsafe操作index(这个index是memoryAddress+index得来的)来操作数据。(但是其实操作jdk底层buffer的时候都是通过unsafe操作的,所以direct的数据最终都是通过unsafe操作的)。
|
|