code-learning/netty/39-Netty 源码解析-Buffer 之 ByteBufAllocator(一)简介.md

498 lines
15 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 精尽 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. 彩蛋
😈 小水文一篇。铺垫铺垫,你懂的。