PoolThreadCache

缓存构成

  PoolThreadCache的缓存由三部分构成:tiny、small 和 normal。

tiny

  缓存数据大小区间为[16B, 496B]数据,数组长度为32,根据数据大小计算索引的办法:数据大小除以16,如下代码所示:

static int tinyIdx(int normCapacity) {
        return normCapacity >>> 4;
    }

small

  缓存数据大小区间为[512B, 4KB]数据,数组长度为4,根据数据大小计算索引的办法:数据大小除以512,然后log2得到指数,如下代码所示:

static int smallIdx(int normCapacity) {
        int tableIdx = 0;
        int i = normCapacity >>> 10;
        while (i != 0) {
            i >>>= 1;
            tableIdx ++;
        }
        return tableIdx;
    }

normal

  索引的计算思路同上。需要注意的是因为Normal的ByteBuf最大容量为16MB,且默认缓存64个,这是巨大的内存开销,所以Netty默认将容量上限设为32KB,即Normal默认可以缓存8KB、16KB和32KB的数据。

这里写图片描述

创建时机

  每个线程首次通过PoolThreadLocalCache获取所属的PoolThreadCache时进行创建,如下:

final class PoolThreadLocalCache extends FastThreadLocal<PoolThreadCache> {
        private final boolean useCacheForAllThreads;

        PoolThreadLocalCache(boolean useCacheForAllThreads) {
            this.useCacheForAllThreads = useCacheForAllThreads;
        }

        @Override
        protected synchronized PoolThreadCache initialValue() {
            final PoolArena<byte[]> heapArena = leastUsedArena(heapArenas);
            final PoolArena<ByteBuffer> directArena = leastUsedArena(directArenas);

            Thread current = Thread.currentThread();
            boolean fastThread = current instanceof FastThreadLocalThread;
            if (useCacheForAllThreads || current instanceof FastThreadLocalThread) {
                // If our FastThreadLocalThread will call FastThreadLocal.removeAll() we not need to use
                // the ThreadDeathWatcher to release memory from the PoolThreadCache once the Thread dies.
                boolean useTheadWatcher = fastThread ?
                        !((FastThreadLocalThread) current).willCleanupFastThreadLocals() : true;
                return new PoolThreadCache(
                        heapArena, directArena, tinyCacheSize, smallCacheSize, normalCacheSize,
                        DEFAULT_MAX_CACHED_BUFFER_CAPACITY, DEFAULT_CACHE_TRIM_INTERVAL, useTheadWatcher);
            }
            // No caching for non FastThreadLocalThreads.
            return new PoolThreadCache(heapArena, directArena, 0, 0, 0, 0, 0, false);
        }

        @Override
        protected void onRemoval(PoolThreadCache threadCache) {
            threadCache.free();
        }

        private <T> PoolArena<T> leastUsedArena(PoolArena<T>[] arenas) {
            if (arenas == null || arenas.length == 0) {
                return null;
            }

            PoolArena<T> minArena = arenas[0];
            for (int i = 1; i < arenas.length; i++) {
                PoolArena<T> arena = arenas[i];
                if (arena.numThreadCaches.get() < minArena.numThreadCaches.get()) {
                    minArena = arena;
                }
            }

            return minArena;
        }
    }

初始化逻辑

  1. 创建tiny、small 和 normal三类缓存数组;
  2. 注册清理任务,当线程不活跃时释放缓存的空间,防止线程意外结束时,没有释放内存空间,造成内存泄露;

参考:

  1. https://www.jianshu.com/p/9177b7dabd37
版权声明:本文为yangguosb原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/yangguosb/article/details/81485030

智能推荐

【Python基础】使用统计函数绘制简单图形

机器学习算法与自然语言处理出品 @公众号原创专栏作者 冯夏冲 学校 | 哈工大SCIR实验室在读博士生 2.1 函数bar 用于绘制柱状图 2.2 函数barh 用于绘制条形图 2.3 函数hist 用于绘制直方图 直方图与柱状图的区别 函数pie 用于绘制饼图 2.5 函数polor 用于绘制极线图 极线图是在极坐标系上绘出的一种图。在极坐标系中,要确定一个点,需要指明这个点距原点的角...

css:顶部按钮固定,上面内容滑动

这种需求我们平时见到很多的,实现方法也多的参差不齐,下面我说一种简单的。如图: 可以看到只有红线部分滚动,底下按钮是固定的。 代码...

环形公路堵车概率模型(含详细解析)

文章目录 基础理论 代码实现 图形分析 基础理论 路面上有n辆车,以不同的速度向前行驶, 模拟堵车问题。 有以下假设: 假设某辆车的当前速度是v。 若前方可见范围内没车,则它在下一秒的车速提高到v+1,直到达到规定的最高限速。 若前方有车,前车的距离为d,且d < v,则它下 一秒的车速降低到d-1 。 每辆车会以概率p随机减速v-1。、 代码实现 图形分析 图形中颜色越重的地方,说明很多车...

JavaScript事件处理的例题

知道的越多,所不知道的越多。如果带给你帮助,点赞支持一下。 JavaScript事件处理的例题 1、表单验证 2、验证数字输入 3、利用document对象的bgColor属性改变背景色,添加鼠标悬停事件 4.附加题(选做) 1、表单验证 要求:用户名不少于2位,并且用户名第一个字符需为字母! 密码长度必须在6~15之间。 2、验证数字输入 如果输入的值 x 不是数字或者小于 1 或者大于 10,...

arduino操作光照传感器BH1750(数字型,I2C接口)

BH1750传感器,用于检测环境光光照强度。 BH1750FVI是日本罗姆(ROHM)半导体生产的数字式环境光传感IC。其主要特性有: I2C数字接口,支持速率最大400Kbps 输出量为光照度(Illuminance) 测量范围1~65535 lux,分辨率最小到1lux 低功耗(Power down)功能 屏蔽50/60Hz市电频率引起的光照变化干扰 支持两个I2C地址,通过ADDR引脚选择 ...

猜你喜欢

10.31 数组算法学习-冒泡、选择、二分法

  冒泡排序:   冒泡排序 https://blog.csdn.net/kelinfeng16/article/details/84034386 原文地址:https://github.com/hustcc/JS-Sorting-Algorithm/blob/master/2.selectionSort.md 冒泡排序(Bubble Sort)也是一种简单直观的排序算法。它重...

排序算法5--交换排序2--快速排序(C++完整代码实现)

以上图片来自天勤数据结构,以下代码***非天勤数据结构提供的代码;*** 平均时间复杂度O(nlog2n)...

C语言0基础笔记--第六回--分钟计算

分钟计算: 改进: 还可以化简下 其他满分:速度快 1:分开从键盘输入,占内存少 2:直接前一个减去后一个,内存占用更少,但是代码更长...

python selenium笔记

selenium链接 selenlum基本使用-操作表单元素,行为链,键盘操作...

5. C++与STL入门

从C到C++ C++模板 C++版的“a+b程序” C++能编译大多数C语言程序。虽然C语言中大多数头文件在C++中仍然可以使用,但推荐方法是在C头文件之前加一个小写的c字母,然后去掉.h后缀。 稍微复杂点的程序 iostream 提供了输入输出流,而algorithm提供了一些常用的算法,例如代码中的min。 cin>> a的含义是从标注中读取a,它的返回值是...