微小型Capacity 小于512
小型Capacity 大于等于512 并且小于 8192(pageSize) ~(8192 - 1) == -8192
PooledByteBufAllocator的newDirectBuffer方法
@Override protected ByteBuf newDirectBuffer(int initialCapacity, int maxCapacity) { PoolThreadCache cache = threadCache.get(); PoolArena<ByteBuffer> directArena = cache.directArena; final ByteBuf buf; if (directArena != null) { buf = directArena.allocate(cache, initialCapacity, maxCapacity); } else { buf = PlatformDependent.hasUnsafe() ? UnsafeByteBufUtil.newUnsafeDirectByteBuf(this, initialCapacity, maxCapacity) : new UnpooledDirectByteBuf(this, initialCapacity, maxCapacity); } return toLeakAwareBuffer(buf); }
PoolThreadCache cache = threadCache.get(); 这行源码的逻辑参考PoolThreadLocalCache源码分析
接下来是这行源码 buf = directArena.allocate(cache, initialCapacity, maxCapacity);
buf = directArena.allocate(cache, initialCapacity, maxCapacity);
进入到PoolArena
PooledByteBuf<T> allocate(PoolThreadCache cache, int reqCapacity, int maxCapacity) { PooledByteBuf<T> buf = newByteBuf(maxCapacity); allocate(cache, buf, reqCapacity); return buf; }
PooledByteBuf<T> buf = newByteBuf(maxCapacity)的具体实现在PoolArena的子类DirectArena中实现
@Override protected PooledByteBuf<ByteBuffer> newByteBuf(int maxCapacity) { if (HAS_UNSAFE) { return PooledUnsafeDirectByteBuf.newInstance(maxCapacity); } else { return PooledDirectByteBuf.newInstance(maxCapacity); } }
这里我们假设HAS_UNSAFE为true,那么执行源码 return PooledUnsafeDirectByteBuf.newInstance(maxCapacity); 这里的逻辑参考PooledUnsafeDirectByteBuf初始化
回到 allocate(cache, buf, reqCapacity); 这里的buf实际是一个PooledUnsafeDirectByteBuf对象
private void allocate(PoolThreadCache cache, PooledByteBuf<T> buf, final int reqCapacity) { final int normCapacity = normalizeCapacity(reqCapacity); ① //小于pageSzie(8192)的为微小型、小型 if (isTinyOrSmall(normCapacity)) { // capacity < pageSize int tableIdx; PoolSubpage<T>[] table; //小于512的为微小型 boolean tiny = isTiny(normCapacity); if (tiny) { // < 512 //当前先讨论第一次分配的逻辑,在这里不会进行分配 if (cache.allocateTiny(this, buf, reqCapacity, normCapacity)) { // was able to allocate out of the cache so move on return; } tableIdx = tinyIdx(normCapacity);② table = tinySubpagePools;② } else { if (cache.allocateSmall(this, buf, reqCapacity, normCapacity)) { // was able to allocate out of the cache so move on return; } tableIdx = smallIdx(normCapacity); table = smallSubpagePools; } final PoolSubpage<T> head = table[tableIdx]; /** * 第一次分配的时候head.next == head 所以不会执行这段逻辑 */ synchronized (head) { final PoolSubpage<T> s = head.next; if (s != head) { assert s.doNotDestroy && s.elemSize == normCapacity; long handle = s.allocate(); assert handle >= 0; s.chunk.in