属性
属性 含义 值 static final Iterator<PoolChunkMetric> EMPTY_METRICS
一个空的Iterator Collections.<PoolChunkMetric>emptyList().iterator() final PoolArena<T> arena
PoolChunkList所属的PoolArena final PoolChunkList<T> nextList
下一个PoolChunkList final int minUsage
最小使用量 final int maxUsage
最大使用量 final int maxCapacity
每个chunk分配的最大容量 PoolChunk<T> head
PoolChunkList维护的Chunk链表的头 PoolChunkList<T> prevList
上一个PoolChunkList
构造方法
PoolChunkList(PoolArena<T> arena, PoolChunkList<T> nextList, int minUsage, int maxUsage, int chunkSize) { assert minUsage <= maxUsage; this.arena = arena; this.nextList = nextList; this.minUsage = minUsage; this.maxUsage = maxUsage; maxCapacity = calculateMaxCapacity(minUsage, chunkSize); } private static int calculateMaxCapacity(int minUsage, int chunkSize) { minUsage = minUsage0(minUsage); if (minUsage == 100) { // 如果minUsage为100,我们将无法分配该列表之外的任何内容。 return 0; } // 计算可从此PoolChunkList中的PoolChunk分配的最大字节数。 // 举例来说: // 如果PoolChunkList的minUsage == 25,则允许我们最多分配chunkSize的75%,因为这是此PoolChunkList中任何PoolChunk中可用的最大数量。PoolChunkList. return (int) (chunkSize * (100L - minUsage) / 100L); }
分配
boolean allocate(PooledByteBuf<T> buf, int reqCapacity, int normCapacity) { if (normCapacity > maxCapacity) { return false; } //循环chunk链表进行分配 for (PoolChunk<T> cur = head; cur != null; cur = cur.next) { //在某个chunk中分配 if (cur.allocate(buf, reqCapacity, normCapacity)) { //判断使用量是否>=最大使用量 if (cur.usage() >= maxUsage) { //将当前chunk从链表中移除 remove(cur); //加入到下一个chunkList中 nextList.add(cur); } return true; } } return false; }
PoolChunk的usage()方法
@Override public int usage() { final int freeBytes; //注意这里 synchronized (arena) { freeBytes = this.freeBytes; } return usage(freeBytes); } private int usage(int freeBytes) { if (freeBytes == 0) { return 100; } int freePercentage = (int) (freeBytes * 100L / chunkSize); if (freePercentage == 0) { return 99; } return 100 - freePercentage; }
PoolChunkList数据结构
各个PoolChunkList之间的关系
分配顺序