微小型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) {

本文深入剖析了PooledByteBuf的分配与回收过程,特别是微小型PooledByteBuf在未命中缓存时的分配细节。从PooledByteBufAllocator初始化开始,讲解PoolThreadCache、PoolArena、PoolChunk、PoolSubpage的初始化,直至PooledByteBuf的创建和回收。详细阐述了容量小于512的微小型、容量在512至8192之间的小型以及普通型PooledByteBuf的分配逻辑,同时解析了PoolChunkList和Recycler的工作原理。
最低0.47元/天 解锁文章
176万+

被折叠的 条评论
为什么被折叠?



