PoolChunkList
看名字,就知道是用來管理PoolChunk的
屬性
private static final Iterator<PoolChunkMetric> EMPTY_METRICS = Collections.<PoolChunkMetric>emptyList().iterator();
private final PoolArena<T> arena;//歸屬PoolArean
private final PoolChunkList<T> nextList;//鏈接下一個PoolChunkList
private final int minUsage;//最小使用率
private final int maxUsage; //最大使用率
private final int maxCapacity;//最大容量
private PoolChunk<T> head;//第一個PoolChunk
// This is only update once when create the linked like list of PoolChunkList in PoolArena constructor.
private PoolChunkList<T> prevList;
重要方法
//用1-最小使用率,就是最大容量了
private static int calculateMaxCapacity(int minUsage, int chunkSize) {
minUsage = minUsage0(minUsage);
if (minUsage == 100) {
// If the minUsage is 100 we can not allocate anything out of this list.
return 0;
}
// Calculate the maximum amount of bytes that can be allocated from a PoolChunk in this PoolChunkList.
//
// As an example:
// - If a PoolChunkList has minUsage == 25 we are allowed to allocate at most 75% of the chunkSize because
// this is the maximum amount available in any PoolChunk in this PoolChunkList.
return (int) (chunkSize * (100L - minUsage) / 100L);
}
//內存分配
boolean allocate(PooledByteBuf<T> buf, int reqCapacity, int normCapacity) {
if (head == null || normCapacity > maxCapacity) {
// Either this PoolChunkList is empty or the requested capacity is larger then the capacity which can
// be handled by the PoolChunks that are contained in this PoolChunkList.
return false;
}
for (PoolChunk<T> cur = head;;) {
long handle = cur.allocate(normCapacity);//從PoolChunk中分配
if (handle < 0) {//分配失敗
cur = cur.next;
if (cur == null) {
return false;
}
} else {
cur.initBuf(buf, handle, reqCapacity); //分配成功,設置 ByteBuf偏移量
if (cur.usage() >= maxUsage) {//當前PoolChunk使用率超過該容器的最大使用率,從該容器中移除,轉移到下一個容器中去
remove(cur);
nextList.add(cur);
}
return true;
}
}
}
//回收內存
boolean free(PoolChunk<T> chunk, long handle) {
chunk.free(handle);//從PoolChunk中回收
if (chunk.usage() < minUsage) {//回收後小於最小使用率,從當前容器中移除,轉移到上一個容器中去
remove(chunk);
// Move the PoolChunk down the PoolChunkList linked-list.
return move0(chunk);
}
return true;
}