Netty內(nèi)存管理器ByteBufAllocator及內(nèi)存分配
ByteBufAllocator 內(nèi)存管理器:
Netty 中內(nèi)存分配有一個最頂層的抽象就是ByteBufAllocator,負責分配所有ByteBuf 類型的內(nèi)存。功能其實不是很多,主要有以下幾個重要的API:

public interface ByteBufAllocator {/**分配一塊內(nèi)存,自動判斷是否分配堆內(nèi)內(nèi)存或者堆外內(nèi)存。
* Allocate a {@link ByteBuf}. If it is a direct or heap buffer depends on the actual implementation.
*/
ByteBuf buffer();/**盡可能地分配一塊堆外直接內(nèi)存,如果系統(tǒng)不支持則分配堆內(nèi)內(nèi)存。
* Allocate a {@link ByteBuf}, preferably a direct buffer which is suitable for I/O.
*/
ByteBuf ioBuffer();/**分配一塊堆內(nèi)內(nèi)存。
* Allocate a heap {@link ByteBuf}.
*/
ByteBuf heapBuffer();/**分配一塊堆外內(nèi)存。
* Allocate a direct {@link ByteBuf}.
*/
ByteBuf directBuffer();/**組合分配,把多個ByteBuf 組合到一起變成一個整體。
* Allocate a {@link CompositeByteBuf}.If it is a direct or heap buffer depends on the actual implementation.
*/
CompositeByteBuf compositeBuffer();
}
到這里有些小伙伴可能會有疑問,以上API 中為什么沒有前面提到的8 中類型的內(nèi)存分配API?下面我們來看ByteBufAllocator 的基本實現(xiàn)類AbstractByteBufAllocator,重點分析主要API 的基本實現(xiàn),比如buffer()方法源碼如下:

public abstract class AbstractByteBufAllocator implements ByteBufAllocator {
@Override
public ByteBuf buffer() {
//判斷是否默認支持directBuffer
if (directByDefault) {
return directBuffer();
}
return heapBuffer();
}
}
我們發(fā)現(xiàn)buffer()方法中做了判斷,是否默認支持directBuffer,如果支持則分配directBuffer,否則分配heapBuffer。directBuffer()方法和heapBuffer()方法的實現(xiàn)邏輯幾乎一致,來看directBuffer()方法:

@Override
public ByteBuf directBuffer() {
//分配大小,初始大小256 默認最大capacity為Integer.MAX
return directBuffer(DEFAULT_INITIAL_CAPACITY, DEFAULT_MAX_CAPACITY);
}
@Override
public ByteBuf directBuffer(int initialCapacity, int maxCapacity) {
if (initialCapacity == 0 && maxCapacity == 0) {
return emptyBuf;
}//校驗初始化大小和最大大小
validate(initialCapacity, maxCapacity);
return newDirectBuffer(initialCapacity, maxCapacity);
}
/**
* Create a direct {@link ByteBuf} with the given initialCapacity and maxCapacity.
*/
protected abstract ByteBuf newDirectBuffer(int initialCapacity, int maxCapacity);

directBuffer()方法有多個重載方法,最終會調(diào)用newDirectBuffer()方法,我們發(fā)現(xiàn)newDirectBuffer()方法其實是一個抽象方法,最終,交給AbstractByteBufAllocator 的子類來實現(xiàn)。同理,我們發(fā)現(xiàn)heapBuffer()方法最終是調(diào)用newHeapBuffer()方法,而newHeapBuffer()方法也是抽象方法,具體交給AbstractByteBufAllocator 的子類實現(xiàn)。AbstractByteBufAllocator 的子類主要有兩個:PooledByteBufAllocator 和UnpooledByteBufAllocator,下面我們來看AbstractByteBufAllocator 子類實現(xiàn)的類結(jié)構圖:

到這里,其實我們還只知道directBuffer、heapBuffer 和pooled、unpooled 的分配規(guī)則,那unsafe 和非unsafe是如何判別的呢?其實,是Netty 自動幫我們判別的,如果操作系統(tǒng)底層支持unsafe 那就采用unsafe 讀寫,否則采用非unsafe 讀寫。我們可以從UnpooledByteBufAllocator 的源碼中驗證一下,來看源碼:

public final class UnpooledByteBufAllocator extends AbstractByteBufAllocator implements ByteBufAllocatorMetricProvider {@Override
protected ByteBuf newHeapBuffer(int initialCapacity, int maxCapacity) {
return PlatformDependent.hasUnsafe() ? new UnpooledUnsafeHeapByteBuf(this, initialCapacity, maxCapacity)
: new UnpooledHeapByteBuf(this, initialCapacity, maxCapacity);
}
@Override
protected ByteBuf newDirectBuffer(int initialCapacity, int maxCapacity) {
ByteBuf buf = PlatformDependent.hasUnsafe() ?
UnsafeByteBufUtil.newUnsafeDirectByteBuf(this, initialCapacity, maxCapacity) :
new UnpooledDirectByteBuf(this, initialCapacity, maxCapacity);
return disableLeakDetector ? buf : toLeakAwareBuffer(buf);
}
}

我們發(fā)現(xiàn)在newHeapBuffer()方法和newDirectBuffer()方法中,分配內(nèi)存判斷PlatformDependent 是否支持Unsafa,如果支持則創(chuàng)建Unsafe 類型的Buffer,否則創(chuàng)建非Unsafe 類型的Buffer。由Netty 幫我們自動判斷了。
