# 精尽 Netty 源码解析 —— Buffer 之 ByteBufAllocator(一)简介 # 1. 概述 本文,我们来分享 ByteBufAllocator 。它是 ByteBuf 的分配器,负责创建 ByteBuf 对象。它的子类类图如下:[![类图](39-Netty 源码解析-Buffer 之 ByteBufAllocator(一)简介.assets/01.png)](http://static.iocoder.cn/images/Netty/2018_08_20/01.png)类图 主要有三个子类: - PreferHeapByteBufAllocator ,倾向创建 **Heap** ByteBuf 的分配器。 - PooledByteBufAllocator ,基于**内存池**的 ByteBuf 的分配器。 - UnpooledByteBufAllocator ,**普通**的 ByteBuf 的分配器。 本文分享上面类图红框部分,后面两篇文章再分别分享 UnpooledByteBufAllocator 和 PooledByteBufAllocator 。 # 2. ByteBufAllocator `io.netty.buffer.ByteBufAllocator` ,ByteBuf 分配器**接口**。 还是老样子,我们逐个来看看每个方法。 ## 2.1 DEFAULT ``` ByteBufAllocator DEFAULT = ByteBufUtil.DEFAULT_ALLOCATOR; ``` - 默认 ByteBufAllocator 对象,通过 `ByteBufUtil.DEFAULT_ALLOCATOR` 中获得。代码如下: ``` static final ByteBufAllocator DEFAULT_ALLOCATOR; static { // 读取 ByteBufAllocator 配置 String allocType = SystemPropertyUtil.get("io.netty.allocator.type", PlatformDependent.isAndroid() ? "unpooled" : "pooled"); allocType = allocType.toLowerCase(Locale.US).trim(); // 读取 ByteBufAllocator 对象 ByteBufAllocator alloc; if ("unpooled".equals(allocType)) { alloc = UnpooledByteBufAllocator.DEFAULT; logger.debug("-Dio.netty.allocator.type: {}", allocType); } else if ("pooled".equals(allocType)) { alloc = PooledByteBufAllocator.DEFAULT; logger.debug("-Dio.netty.allocator.type: {}", allocType); } else { alloc = PooledByteBufAllocator.DEFAULT; logger.debug("-Dio.netty.allocator.type: pooled (unknown: {})", allocType); } DEFAULT_ALLOCATOR = alloc; // ... 省略无关代码 } ``` - 在非 Android 环境下,使用 PooledByteBufAllocator 作为默认 ByteBufAllocator 对象。 - 在 Android 环境下,使用 UnpooledByteBufAllocator 作为默认 ByteBufAllocator 对象。因为 Android 客户端的内存相对有限。 ## 2.2 buffer `#buffer(...)` 方法,创建一个 ByteBuf 对象。具体创建的是 Heap ByteBuf 还是 Direct ByteBuf ,由实现类决定。 ``` /** * Allocate a {@link ByteBuf}. If it is a direct or heap buffer * depends on the actual implementation. */ ByteBuf buffer(); ByteBuf buffer(int initialCapacity); ByteBuf buffer(int initialCapacity, int maxCapacity); ``` ### 2.2.1 ioBuffer `#ioBuffer(...)` 方法,创建一个用于 IO 操作的 ByteBuf 对象。倾向于 Direct ByteBuf ,因为对于 IO 操作来说,性能更优。 ``` /** * Allocate a {@link ByteBuf}, preferably a direct buffer which is suitable for I/O. */ ByteBuf ioBuffer(); ByteBuf ioBuffer(int initialCapacity); ByteBuf ioBuffer(int initialCapacity, int maxCapacity); ``` ### 2.2.2 heapBuffer `#heapBuffer(...)` 方法,创建一个 Heap Buffer 对象。代码如下: ``` /** * Allocate a heap {@link ByteBuf}. */ ByteBuf heapBuffer(); ByteBuf heapBuffer(int initialCapacity); ByteBuf heapBuffer(int initialCapacity, int maxCapacity); ``` ### 2.2.3 directBuffer `#directBuffer(...)` 方法,创建一个 Direct Buffer 对象。代码如下: ``` /** * Allocate a direct {@link ByteBuf} with the given initial capacity. */ ByteBuf directBuffer(int initialCapacity); ByteBuf directBuffer(int initialCapacity, int maxCapacity); CompositeByteBuf compositeBuffer(); ``` ## 2.3 compositeBuffer `#compositeBuffer(...)` 方法,创建一个 Composite ByteBuf 对象。具体创建的是 Heap ByteBuf 还是 Direct ByteBuf ,由实现类决定。 ``` /** * Allocate a {@link CompositeByteBuf}. * If it is a direct or heap buffer depends on the actual implementation. */ CompositeByteBuf compositeBuffer(); CompositeByteBuf compositeBuffer(int maxNumComponents); ``` ### 2.3.1 compositeHeapBuffer `#compositeHeapBuffer(...)` 方法,创建一个 Composite Heap ByteBuf 对象。代码如下: ``` /** * Allocate a heap {@link CompositeByteBuf}. */ CompositeByteBuf compositeHeapBuffer(); CompositeByteBuf compositeHeapBuffer(int maxNumComponents); ``` ### 2.3.2 compositeDirectBuffer `#compositeDirectBuffer(...)` 方法,创建一个 Composite Direct ByteBuf 对象。代码如下: ``` /** * Allocate a direct {@link CompositeByteBuf}. */ CompositeByteBuf compositeDirectBuffer(); CompositeByteBuf compositeDirectBuffer(int maxNumComponents); ``` ## 2.4 isDirectBufferPooled `#isDirectBufferPooled()` 方法,是否基于 Direct ByteBuf 对象池。代码如下: ``` /** * Returns {@code true} if direct {@link ByteBuf}'s are pooled */ boolean isDirectBufferPooled(); ``` ## 2.5 calculateNewCapacity `#calculateNewCapacity(int minNewCapacity, int maxCapacity)` 方法,在 ByteBuf 扩容时,计算新的容量,该容量的值在 `[minNewCapacity, maxCapacity]` 范围内。代码如下: ``` /** * Calculate the new capacity of a {@link ByteBuf} that is used when a {@link ByteBuf} needs to expand by the * {@code minNewCapacity} with {@code maxCapacity} as upper-bound. */ int calculateNewCapacity(int minNewCapacity, int maxCapacity); ``` # 3. AbstractByteBufAllocator `io.netty.buffer.AbstractByteBufAllocator` ,实现 ByteBufAllocator 接口,ByteBufAllocator 抽象实现类,为 PooledByteBufAllocator 和 UnpooledByteBufAllocator 提供公共的方法。 ## 3.1 构造方法 ``` /** * 是否倾向创建 Direct ByteBuf */ private final boolean directByDefault; /** * 空 ByteBuf 缓存 */ private final ByteBuf emptyBuf; /** * Instance use heap buffers by default */ protected AbstractByteBufAllocator() { this(false); } /** * Create new instance * * @param preferDirect {@code true} if {@link #buffer(int)} should try to allocate a direct buffer rather than * a heap buffer */ protected AbstractByteBufAllocator(boolean preferDirect) { directByDefault = preferDirect && PlatformDependent.hasUnsafe(); // 支持 Unsafe emptyBuf = new EmptyByteBuf(this); } ``` - `directByDefault` 属性,是否倾向创建 Direct ByteBuf 。有一个前提是需要支持 Unsafe 操作。 - `emptyBuf` 属性,空 ByteBuf 缓存对象。用于 `#buffer()` 等方法,创建**空** ByteBuf 对象时。 ## 3.2 buffer ``` @Override public ByteBuf buffer() { if (directByDefault) { return directBuffer(); } return heapBuffer(); } @Override public ByteBuf buffer(int initialCapacity) { if (directByDefault) { return directBuffer(initialCapacity); } return heapBuffer(initialCapacity); } @Override public ByteBuf buffer(int initialCapacity, int maxCapacity) { if (directByDefault) { return directBuffer(initialCapacity, maxCapacity); } return heapBuffer(initialCapacity, maxCapacity); } ``` - 根据 `directByDefault` 的值,调用 `#directBuffer(...)` 方法,还是调用 `#heapBuffer(...)` 方法。 ### 3.2.1 ioBuffer ``` /** * 默认容量大小 */ static final int DEFAULT_INITIAL_CAPACITY = 256; @Override public ByteBuf ioBuffer() { if (PlatformDependent.hasUnsafe()) { return directBuffer(DEFAULT_INITIAL_CAPACITY); } return heapBuffer(DEFAULT_INITIAL_CAPACITY); } @Override public ByteBuf ioBuffer(int initialCapacity) { if (PlatformDependent.hasUnsafe()) { return directBuffer(initialCapacity); } return heapBuffer(initialCapacity); } @Override public ByteBuf ioBuffer(int initialCapacity, int maxCapacity) { if (PlatformDependent.hasUnsafe()) { return directBuffer(initialCapacity, maxCapacity); } return heapBuffer(initialCapacity, maxCapacity); } ``` - 根据是否支持 Unsafe 操作的情况,调用 `#directBuffer(...)` 方法,还是调用 `#heapBuffer(...)` 方法。 ### 3.2.2 heapBuffer ``` /** * 默认最大容量大小,无限。 */ static final int DEFAULT_MAX_CAPACITY = Integer.MAX_VALUE; @Override public ByteBuf heapBuffer() { return heapBuffer(DEFAULT_INITIAL_CAPACITY, DEFAULT_MAX_CAPACITY); } @Override public ByteBuf heapBuffer(int initialCapacity) { return heapBuffer(initialCapacity, DEFAULT_MAX_CAPACITY); } @Override public ByteBuf heapBuffer(int initialCapacity, int maxCapacity) { // 空 ByteBuf 对象 if (initialCapacity == 0 && maxCapacity == 0) { return emptyBuf; } validate(initialCapacity, maxCapacity); // 校验容量的参数 // 创建 Heap ByteBuf 对象 return newHeapBuffer(initialCapacity, maxCapacity); } ``` - 最终调用 `#newHeapBuffer(int initialCapacity, int maxCapacity)` **抽象**方法,创建 Heap ByteBuf 对象。代码如下: ``` /** * Create a heap {@link ByteBuf} with the given initialCapacity and maxCapacity. */ protected abstract ByteBuf newHeapBuffer(int initialCapacity, int maxCapacity); ``` - 因为是否基于对象池的方式,创建 Heap ByteBuf 对象的实现会不同,所以需要抽象。 ### 3.2.3 directBuffer ``` @Override public ByteBuf directBuffer() { return directBuffer(DEFAULT_INITIAL_CAPACITY, DEFAULT_MAX_CAPACITY); } @Override public ByteBuf directBuffer(int initialCapacity) { return directBuffer(initialCapacity, DEFAULT_MAX_CAPACITY); } @Override public ByteBuf directBuffer(int initialCapacity, int maxCapacity) { // 空 ByteBuf 对象 if (initialCapacity == 0 && maxCapacity == 0) { return emptyBuf; } validate(initialCapacity, maxCapacity); // 校验容量的参数 // 创建 Direct ByteBuf 对象 return newDirectBuffer(initialCapacity, maxCapacity); } ``` - 最终调用 `#newDirectBuffer(int initialCapacity, int maxCapacity)` **抽象**方法,创建 Direct ByteBuf 对象。代码如下: ``` /** * Create a direct {@link ByteBuf} with the given initialCapacity and maxCapacity. */ protected abstract ByteBuf newDirectBuffer(int initialCapacity, int maxCapacity); ``` - 因为是否基于对象池的方式,创建 Direct ByteBuf 对象的实现会不同,所以需要抽象。 ## 3.3 compositeBuffer ``` @Override public CompositeByteBuf compositeBuffer() { if (directByDefault) { return compositeDirectBuffer(); } return compositeHeapBuffer(); } @Override public CompositeByteBuf compositeBuffer(int maxNumComponents) { if (directByDefault) { return compositeDirectBuffer(maxNumComponents); } return compositeHeapBuffer(maxNumComponents); } ``` - 根据 `directByDefault` 的值,调用 `#compositeDirectBuffer(...)` 方法,还是调用 `#compositeHeapBuffer(...)` 方法。 ### 3.3.1 compositeHeapBuffer ``` /** * Composite ByteBuf 可包含的 ByteBuf 的最大数量 */ static final int DEFAULT_MAX_COMPONENTS = 16; @Override public CompositeByteBuf compositeHeapBuffer() { return compositeHeapBuffer(DEFAULT_MAX_COMPONENTS); } @Override public CompositeByteBuf compositeHeapBuffer(int maxNumComponents) { return toLeakAwareBuffer(new CompositeByteBuf(this, false, maxNumComponents)); } ``` - 创建 CompositeByteBuf 对象,并且方法参数 `direct` 为 `false` ,表示 Heap 类型。 - 调用 `#toLeakAwareBuffer(CompositeByteBuf)` 方法,装饰成 LeakAware 的 ByteBuf 对象。 ### 3.3.2 compositeDirectBuffer ``` @Override public CompositeByteBuf compositeDirectBuffer() { return compositeDirectBuffer(DEFAULT_MAX_COMPONENTS); } @Override public CompositeByteBuf compositeDirectBuffer(int maxNumComponents) { return toLeakAwareBuffer(new CompositeByteBuf(this, true, maxNumComponents)); } ``` - 创建 CompositeByteBuf 对象,并且方法参数 `direct` 为 `true` ,表示 Direct 类型。 - 调用 `#toLeakAwareBuffer(CompositeByteBuf)` 方法,装饰成 LeakAware 的 ByteBuf 对象。 ## 3.4 toLeakAwareBuffer 在 [《精尽 Netty 源码解析 —— Buffer 之 ByteBuf(三)内存泄露检测》](http://svip.iocoder.cn/Netty/ByteBuf-1-3-ByteBuf-resource-leak-detector) 中的 [「3.1 创建 LeakAware ByteBuf 对象」](https://svip.iocoder.cn/Netty/ByteBuf-2-1-ByteBufAllocator-intro/#) 小节,已经详细解析。 ## 3.5 calculateNewCapacity ``` /** * 扩容分界线,4M */ static final int CALCULATE_THRESHOLD = 1048576 * 4; // 4 MiB page 1: @Override 2: public int calculateNewCapacity(int minNewCapacity, int maxCapacity) { 3: if (minNewCapacity < 0) { 4: throw new IllegalArgumentException("minNewCapacity: " + minNewCapacity + " (expected: 0+)"); 5: } 6: if (minNewCapacity > maxCapacity) { 7: throw new IllegalArgumentException(String.format( 8: "minNewCapacity: %d (expected: not greater than maxCapacity(%d)", 9: minNewCapacity, maxCapacity)); 10: } 11: final int threshold = CALCULATE_THRESHOLD; // 4 MiB page 12: 13: // <1> 等于 threshold ,直接返回 threshold 。 14: if (minNewCapacity == threshold) { 15: return threshold; 16: } 17: 18: // <2> 超过 threshold ,增加 threshold ,不超过 maxCapacity 大小。 19: // If over threshold, do not double but just increase by threshold. 20: if (minNewCapacity > threshold) { 21: int newCapacity = minNewCapacity / threshold * threshold; 22: if (newCapacity > maxCapacity - threshold) { // 不超过 maxCapacity 23: newCapacity = maxCapacity; 24: } else { 25: newCapacity += threshold; 26: } 27: return newCapacity; 28: } 29: 30: // <3> 未超过 threshold ,从 64 开始两倍计算,不超过 4M 大小。 31: // Not over threshold. Double up to 4 MiB, starting from 64. 32: int newCapacity = 64; 33: while (newCapacity < minNewCapacity) { 34: newCapacity <<= 1; 35: } 36: return Math.min(newCapacity, maxCapacity); 37: } ``` - 按照 `CALCULATE_THRESHOLD` 作为分界线,分成 3 种情况:`<1>`/`<2>`/`<3>` 。代码比较简单,胖友自己看注释。 # 4. PreferHeapByteBufAllocator `io.netty.channel.PreferHeapByteBufAllocator` ,实现 ByteBufAllocator 接口,**倾向创建 Heap ByteBuf** 的分配器。也就是说,`#buffer(...)` 和 `#ioBuffer(...)` 和 `#compositeBuffer(...)` 方法,创建的都是 Heap ByteBuf 对象。代码如下: ``` /** * 真正的分配器对象 */ private final ByteBufAllocator allocator; public PreferHeapByteBufAllocator(ByteBufAllocator allocator) { this.allocator = ObjectUtil.checkNotNull(allocator, "allocator"); } @Override public ByteBuf buffer() { return allocator.heapBuffer(); } @Override public ByteBuf ioBuffer() { return allocator.heapBuffer(); } @Override public CompositeByteBuf compositeBuffer() { return allocator.compositeHeapBuffer(); } ``` 其它方法,就是调用 `allocator` 的对应的方法。 # 666. 彩蛋 😈 小水文一篇。铺垫铺垫,你懂的。