属性 含义 值 static final boolean HAS_UNSAFE
是否有UNSAFE
PlatformDependent.hasUnsafe()
static final int numTinySubpagePools
微小子页池中页的数量 512 >>> 4 也就是32 final PooledByteBufAllocator parent
属于哪个分配器 private final int maxOrder
指数,与pageSize一起决定chunk的大小 11 final int pageSize
页的大小 8192 final int pageShifts
页大小的位移,本质上是pageSize的二进制从右开始第一个1的右面0的数量,如pageSize=2 则 pageShifts=1,在这里pageSize=8192,pageShifts=13 13 final int chunkSize
chunk的大小 8192 << 11 也就是16MB final int subpageOverflowMask
子页面溢出掩码,主要作用是判断某个size是否小于pageSize
如果size & subpageOverflowMask == 0 那么 size小于pageSize
~(page -1) page-1=8191 二进制为 0000 0000 0000 0000 000 1111 1111 1111 1
再取反后变为 1111 1111 1111 1111 111 0000 0000 0000 0
final int numSmallSubpagePools
小型子页面池中页的数量 pageShifts - 9 = 4 final int directMemoryCacheAlignment final int directMemoryCacheAlignmentMask private final PoolSubpage<T>[] tinySubpagePools
微小型子页面池
它是一个长度为32的PoolSubpage数组,其中每个元素代表了一种微小型内存的大小(均为16的位数)
如tinySubpagePools[0] 代表0B,tinySubpagePools[1] 代表16B,tinySubpagePools[2] 代表32B,依此类推,最大496B。
tinySubpagePools = new PoolSubpage[numTinySubpagePools] for (int i = 0; i < tinySubpagePools.length; i ++) { tinySubpagePools[i] = newSubpagePoolHead(pageSize); } private PoolSubpage<T> newSubpagePoolHead(int pageSize) { PoolSubpage<T> head = new PoolSubpage<T>(pageSize); head.prev = head; head.next = head; return head; }
private final PoolSubpage<T>[] smallSubpagePools
小型子页面池 smallSubpagePools = new PoolSubpage[numSmallSubpagePools]; for (int i = 0; i < smallSubpagePools.length; i ++) { smallSubpagePools[i] = newSubpagePoolHead(pageSize); } private PoolSubpage<T> newSubpagePoolHead(int pageSize) { PoolSubpage<T> head = new PoolSubpage<T>(pageSize); head.prev = head; head.next = head; return head; }
private final PoolChunkList<T> q050 Chunk池 本质上是一个双向链表 new PoolChunkList<T>(this, q075, 50, 100, chunkSize) 最小使用量为50,最大使用量100
q050.prevList(q025);
private final PoolChunkList<T> q025 Chunk池 本质上是一个双向链表 new PoolChunkList<T>(this, q050, 25, 75, chunkSize) 最小使用量为25,最大使用量75
q025.prevList(q000)
private final PoolChunkList<T> q000 Chunk池 本质上是一个双向链表 new PoolChunkList<T>(this, q025, 1, 50, chunkSize) 最小使用量为1,最大使用量50
q000.prevList(null)
private final PoolChunkList<T> qInit Chunk池 本质上是一个双向链表 new PoolChunkList<T>(this, q000, Integer.MIN_VALUE, 25, chunkSize) 最小使用量为Integer.MIN_VALUE,最大使用量25
qInit.prevList(qInit)
private final PoolChunkList<T> q075 Chunk池 本质上是一个双向链表 new PoolChunkList<T>(this, q100, 75, 100, chunkSize) 最小使用量为75,最大使用量100
q075.prevList(q050);
private final PoolChunkList<T> q100 Chunk池 本质上是一个双向链表 new PoolChunkList<T>(this, null, 100, Integer.MAX_VALUE, chunkSize) 最小使用量为100,最大使用量Integer.MAX_VALUE
q100.prevList(q075);private final List<PoolChunkListMetric> chunkListMetrics List<PoolChunkListMetric> metrics = new ArrayList<PoolChunkListMetric>(6); metrics.add(qInit); metrics.add(q000); metrics.add(q025); metrics.add(q050); metrics.add(q075); metrics.add(q100); chunkListMetrics = Collections.unmodifiableList(metrics);
private long allocationsNormal
分配和解除分配的指标 private final LongCounter allocationsTiny
PlatformDependent.newLongCounter() private final LongCounter allocationsSmall PlatformDependent.newLongCounter() private final LongCounter allocationsHuge PlatformDependent.newLongCounter() private final LongCounter activeBytesHuge PlatformDependent.newLongCounter() private long deallocationsTiny private long deallocationsSmall private long deallocationsNormal private final LongCounter deallocationsHuge PlatformDependent.newLongCounter() final AtomicInteger numThreadCaches 使用此区域的线程数量 new AtomicInteger()
构造方法
protected PoolArena(PooledByteBufAllocator parent, int pageSize,
int maxOrder, int pageShifts, int chunkSize, int cacheAlignment) {
this.parent = parent;
this.pageSize = pageSize;
this.maxOrder = maxOrder;
this.pageShifts = pageShifts;
this.chunkSize = chunkSize;
directMemoryCacheAlignment = cacheAlignment;
directMemoryCacheAlignmentMask = cacheAlignment - 1;
subpageOverflowMask = ~(pageSize - 1);
tinySubpagePools = newSubpagePoolArray(numTinySubpagePools);
for (int i = 0; i < tinySubpagePools.length; i ++) {
tinySubpagePools[i] = newSubpagePoolHead(pageSize);
}
numSmallSubpagePools = pageShifts - 9;
smallSubpagePools = newSubpagePoolArray(numSmallSubpagePools);
for (int i = 0; i < smallSubpagePools.length; i ++) {
smallSubpagePools[i] = newSubpagePoolHead(pageSize);
}
q100 = new PoolChunkList<T>(this, null, 100, Integer.MAX_VALUE, chunkSize);
q075 = new PoolChunkList<T>(this, q100, 75, 100, chunkSize);
q050 = new PoolChunkList<T>(this, q075, 50, 100, chunkSize);
q025 = new PoolChunkList<T>(this, q050, 25, 75, chunkSize);
q000 = new PoolChunkList<T>(this, q025, 1, 50, chunkSize);
qInit = new PoolChunkList<T>(this, q000, Integer.MIN_VALUE, 25, chunkSize);
q100.prevList(q075);
q075.prevList(q050);
q050.prevList(q025);
q025.prevList(q000);
q000.prevList(null);
qInit.prevList(qInit);
List<PoolChunkListMetric> metrics = new ArrayList<PoolChunkListMetric>(6);
metrics.add(qInit);
metrics.add(q000);
metrics.add(q025);
metrics.add(q050);
metrics.add(q075);
metrics.add(q100);
chunkListMetrics = Collections.unmodifiableList(metrics);
}