zoukankan      html  css  js  c++  java
  • PoolChunkList

    概述(Motivation)

    chunklist

    实现细节(Modification)

    主要成员

    private final PoolArena<T> arena;
        private final PoolChunkList<T> nextList;
        private final int minUsage;
        private final int maxUsage;
    	// poolChunkList存放的都是同一种chunk,所以初始化的时候根据chunkSize*(1-minUsage)
    	// 因为此List中的chunk使用率最低是minUsage,所以最多只能分配(1-minUsage)
        private final int maxCapacity;
        private PoolChunk<T> head;
    
        // This is only update once when create the linked like list of PoolChunkList in PoolArena constructor.
        private PoolChunkList<T> prevList;
    

    分配函数

        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);
                if (handle < 0) {
                    cur = cur.next;
                    if (cur == null) {
                        return false;
                    }
                } else {
                    // 分配成功
                    cur.initBuf(buf, handle, reqCapacity);
                    // 超过使用率会将chunk转移到下一个list
                    if (cur.usage() >= maxUsage) {
                        remove(cur);
                        nextList.add(cur);
                    }
                    return true;
                }
            }
        }
    

    释放函数

     boolean free(PoolChunk<T> chunk, long handle) {
            chunk.free(handle);
            // 如果释放后当前使用量低于限定值,移动到前一个
            if (chunk.usage() < minUsage) {
                // chunkList自身指针的操作去除该chunk结点
                remove(chunk);
                // Move the PoolChunk down the PoolChunkList linked-list.
                // 该chunk进行移动
                return move0(chunk);
            }
            return true;
        }
    
         /**
         * Moves the {@link PoolChunk} down the {@link PoolChunkList} linked-list so it will end up in the right
         * {@link PoolChunkList} that has the correct minUsage / maxUsage in respect to {@link PoolChunk#usage()}.
         */
        private boolean move0(PoolChunk<T> chunk) {
            if (prevList == null) {
                // There is no previous PoolChunkList so return false which result in having the PoolChunk destroyed and
                // all memory associated with the PoolChunk will be released.
                // 调用者的逻辑会将该chunk进行destroy处理
                assert chunk.usage() == 0;
                return false;
            }
            return prevList.move(chunk);
        }
    
      private boolean move(PoolChunk<T> chunk) {
            assert chunk.usage() < maxUsage;
    
            if (chunk.usage() < minUsage) {
                // Move the PoolChunk down the PoolChunkList linked-list.
                return move0(chunk);
            }
    
            // PoolChunk fits into this PoolChunkList, adding it here.
            // chunkList自身指针的操作加入该chunk结点
            add0(chunk);
            return true;
        }
    

    分配顺序

    之前在poolArena中,分配的顺序是50->25->00->init->75。

    网上基本就一个观点。。高峰期分配内存容易释放掉不会堆积。

    我觉得一个网络一般是稳定,那么意味着我们希望保持一个高使用率的内存,避免浪费,所以从50起是一个适中值堆积起一些常用的内存。当然50确实是个适中值,基本上所有情况下你都可以说中位数是一个合理值。。

    综述(Result)

    一个描述使用率的链表,将不同使用率的chunk分开,从而能更合理的分配和释放内存。

  • 相关阅读:
    linux--文件夹下批量改动IP
    Effective C++ 条款24
    ARMv8 Linux内核异常处理过程分析
    VS2010升级VS2013后,出现没有定义类型“PowerPacks.ShapeContainer”错误解决方法
    利用Nginx构建负载均衡server
    getline与get函数的区别
    Linking Containers Together
    获取不同机型外置SD卡路径
    查看linux系统状态
    Linux 开机自检的设置(tune2fs和fsck)
  • 原文地址:https://www.cnblogs.com/GrimReaper/p/10385330.html
Copyright © 2011-2022 走看看