深入淺出Netty內存管理:PoolChunkList

JosMLXB 8年前發布 | 30K 次閱讀 Netty 鏈表 網絡工具包

本文主要分析管理PoolChunk生命周期的PoolChunkList。

PoolChunkList

PoolChunkList負責管理多個chunk的生命周期,在此基礎上對內存分配進行進一步的優化。

final class PoolChunkList<T> implements PoolChunkListMetric {
 
    private final PoolChunkList<T> nextList;
    private final int minUsage;
    private final int maxUsage;
 
    private PoolChunk<T> head;
    private PoolChunkList<T> prevList;
    ...
}

從代碼實現可以看出,每個PoolChunkList實例維護了一個PoolChunk鏈表,自身也形成一個鏈表,為何要這么實現?

隨著chunk中page的不斷分配和釋放,會導致很多碎片內存段,大大增加了之后分配一段連續內存的失敗率,針對這種情況,可以把內存使用率較大的chunk放到PoolChunkList鏈表更后面,具體實現如下:

boolean allocate(PooledByteBuf<T> buf, int reqCapacity, int normCapacity) {
    if (head == null) {
        return false;
    }
 
    for (PoolChunk<T> cur = head;;) {
        long handle = cur.allocate(normCapacity);
        if (handle < 0) {
            cur = cur.next;
            if (cur == null) {
                return false;
            }
        } else {
            cur.initBuf(buf, handle, reqCapacity);
            if (cur.usage() >= maxUsage) {  // (1)
                remove(cur);
                nextList.add(cur);
            }
            return true;
        }
    }
}

假設poolChunkList中已經存在多個chunk。當分配完內存后,如果當前chunk的使用量超過maxUsage,則把該chunk從當前鏈表中刪除,添加到下一個鏈表中。

但是,隨便chunk中內存的釋放,其內存使用率也會隨著下降,當下降到minUsage時,該chunk會移動到前一個列表中,實現如下:

boolean free(PoolChunk<T> chunk, long handle) {
    chunk.free(handle);
    if (chunk.usage() < minUsage) {
        remove(chunk);
        if (prevList == null) {
            assert chunk.usage() == 0;
            return false;
        } else {
            prevList.add(chunk);
            return true;
        }
    }
    return true;
}

從poolChunkList的實現可以看出,每個chunkList的都有一個上下限:minUsage和maxUsage,兩個相鄰的chunkList,前一個的maxUsage和后一個的minUsage必須有一段交叉值進行緩沖,否則會出現某個chunk的usage處于臨界值,而導致不停的在兩個chunk間移動。

所以chunk的生命周期不會固定在某個chunkList中,隨著內存的分配和釋放,根據當前的內存使用率,在chunkList鏈表中前后移動。

 

來自:http://blog.jobbole.com/106085/

 

 本文由用戶 JosMLXB 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!