Netty源码分析(八) PoolChunkList

2018-11-08  本文已影响0人  skyguard

前面我们说到了Netty的内存管理机制,也讨论了PoolChunk的内存分配算法,但是PoolChunk只有16M,这远远不够用,所以会有很多很多PoolChunk,这些PoolChunk组成一个链表,然后用PoolChunkList持有这个链表。下面就来介绍一下PoolChunkList。
先看一下PoolChunkList有哪些属性

/**
 * 所属 PoolArena 对象
 */
private final PoolArena<T> arena;
/**
 * 下一个 PoolChunkList 对象
 */
private final PoolChunkList<T> nextList;
/**
 * Chunk 最小内存使用率
 */
private final int minUsage;
/**
 * Chunk 最大内存使用率
 */
private final int maxUsage;
/**
 * 每个 Chunk 最大可分配的容量
 *
 * @see #calculateMaxCapacity(int, int) 方法
 */
private final int maxCapacity;
/**
 * PoolChunk 头节点
 */
private PoolChunk<T> head;

/**
 * 前一个 PoolChunkList 对象
 */
// This is only update once when create the linked like list of PoolChunkList in PoolArena constructor.
private PoolChunkList<T> prevList;

PoolChunkList包含了一个prev和一个next,组成了一个链表。既然按使用率分配,那么PoolChunk在使用过程中是会动态变化的,所以PoolChunk会在不同PoolChunkList中变化。同时申请空间,使用哪一个PoolChunkList也是有先后顺序的。下面我们来看看PoolChunkList是怎么分配内存的。

boolean allocate(PooledByteBuf<T> buf, int reqCapacity, int normCapacity) {
    // 双向链表中无 Chunk
    // 申请分配的内存超过 ChunkList 的每个 Chunk 最大可分配的容量
    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;
    }

    // 遍历双向链表。注意,遍历的是 ChunkList 的内部双向链表。
    for (PoolChunk<T> cur = head;;) {
        // 分配内存块
        long handle = cur.allocate(normCapacity);
        // 分配失败
        if (handle < 0) {
            // 进入下一节点
            cur = cur.next;
            // 若下一个节点不存在,返回 false ,结束循环
            if (cur == null) {
                return false; // 分配失败
            }
        // 分配成功
        } else {
            // 初始化内存块到 PooledByteBuf 对象中
            cur.initBuf(buf, handle, reqCapacity);
            // 超过当前 ChunkList 管理的 Chunk 的内存使用率上限
            if (cur.usage() >= maxUsage) {
                // 从当前 ChunkList 节点移除
                remove(cur);
                // 添加到下一个 ChunkList 节点
                nextList.add(cur);
            }
            return true; // 分配成功
        }
    }
}

PoolChunkList的分析就到这里了。

上一篇 下一篇

猜你喜欢

热点阅读