千家信息网

如何理解Netty内存管理 PoolChunk

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,这期内容当中小编将会给大家带来有关如何理解Netty内存管理 PoolChunk,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。多年之前,从C内存的手动管理上升到ja
千家信息网最后更新 2026年11月03日如何理解Netty内存管理 PoolChunk

这期内容当中小编将会给大家带来有关如何理解Netty内存管理 PoolChunk,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

多年之前,从C内存的手动管理上升到java的自动GC,是历史的巨大进步。然而多年之后,netty的内存实现又曲线的回到了手动管理模式,正印证了马克思哲学观:社会总是在螺旋式前进的,没有永远的最好。的确,就内存管理而言,GC给程序员带来的价值是不言而喻的,不仅大大的降低了程序员的负担,而且也极大的减少了内存管理带来的Crash困扰,不过也有很多情况,可能手动的内存管理更为合适。
接下去准备几个篇幅对Netty的内存管理进行深入分析。
PoolChunk
为了能够简单的操作内存,必须保证每次分配到的内存时连续的。Netty中底层的内存分配和回收管理主要由PoolChunk实现,其内部维护一棵平衡二叉树memoryMap,所有子节点管理的内存也属于其父节点。


poolChunk默认由2048个page组成,一个page默认大小为8k,图中节点的值为在数组memoryMap的下标。
1、如果需要分配大小8k的内存,则只需要在第11层,找到第一个可用节点即可。
2、如果需要分配大小16k的内存,则只需要在第10层,找到第一个可用节点即可。
3、如果节点1024存在一个已经被分配的子节点2048,则该节点不能被分配,如需要分配大小16k的内存,这个时候节点2048已被分配,节点2049未被分配,就不能直接分配节点1024,因为该节点目前只剩下8k内存。
poolChunk内部会保证每次分配内存大小为8K*(2n),为了分配一个大小为chunkSize/(2k)的节点,需要在深度为k的层从左开始匹配节点,那么如何快速的分配到指定内存?
memoryMap初始化:

memoryMap = new byte[maxSubpageAllocs << 1];depthMap = new byte[memoryMap.length];int memoryMapIndex = 1;for (int d = 0; d <= maxOrder; ++ d) { // move down the tree one level at a time    int depth = 1 << d;    for (int p = 0; p < depth; ++ p) {        // in each level traverse left to right and set value to the depth of subtree        memoryMap[memoryMapIndex] = (byte) d;        depthMap[memoryMapIndex] = (byte) d;        memoryMapIndex ++;    }}

memoryMap数组中每个位置保存的是该节点所在的层数,有什么作用?对于节点512,其层数是9,则:
1、如果memoryMap[512] = 9,则表示其本身到下面所有的子节点都可以被分配;
2、如果memoryMap[512] = 10, 则表示节点512下有子节点已经分配过,则该节点不能直接被分配,而其子节点中的第10层还存在未分配的节点;
3、如果memoryMap[512] = 12 (即总层数 + 1), 可分配的深度已经大于总层数, 则表示该节点下的所有子节点都已经被分配。
下面看看如何向PoolChunk申请一段内存:

long allocate(int normCapacity) {    if ((normCapacity & subpageOverflowMask) != 0) { // >= pageSize        return allocateRun(normCapacity);    } else {        return allocateSubpage(normCapacity);    }}

1、当需要分配的内存大于pageSize时,使用allocateRun实现内存分配。
2、否则使用方法allocateSubpage分配内存,在allocateSubpage实现中,会把一个page分割成多段,进行内存分配。

这里先看看allocateRun是如何实现的:

private long allocateRun(int normCapacity) {    int d = maxOrder - (log2(normCapacity) - pageShifts);    int id = allocateNode(d);    if (id < 0) {        return id;    }    freeBytes -= runLength(id);    return id;}

1、normCapacity是处理过的值,如申请大小为1000的内存,实际申请的内存大小为1024。
2、d = maxOrder - (log2(normCapacity) - pageShifts) 可以确定需要在二叉树的d层开始节点匹配。
其中pageShifts默认值为13,为何是13?因为只有当申请内存大小大于2^13(8192)时才会使用方法allocateRun分配内存。
3、方法allocateNode实现在二叉树中进行节点匹配,具体实现如下:

private int allocateNode(int d) {    int id = 1;    int initial = - (1 << d);     //value(id)=memoryMap[id]     byteval = value(id);     if (val > d) { // unusable        return -1;    }    while (val < d || (id & initial) == 0) { // id & initial == 1 << d for all ids at depth d, for < d it is 0        id <<= 1;        val = value(id);        if (val > d) {            id ^= 1;            val = value(id);        }    }    byte value = value(id);    assert value == d && (id & initial) == 1 << d : String.format("val = %d, id & initial = %d, d = %d",            value, id & initial, d);    setValue(id, unusable); // mark as unusable    updateParentsAlloc(id);    return id;}

1、从根节点开始遍历,如果当前节点的val2、如果val > d,则表示存在子节点被分配的情况,而且剩余节点的内存大小不够,此时需要在兄弟节点上继续查找;
3、分配成功的节点需要标记为不可用,防止被再次分配,在memoryMap对应位置更新为12;
4、分配节点完成后,其父节点的状态也需要更新,并可能引起更上一层父节点的更新,实现如下:

private void updateParentsAlloc(int id) {    while (id > 1) {        int parentId = id >>> 1;        byte val1 = value(id);        byte val2 = value(id ^ 1);        byteval = val1 < val2 ? val1 : val2;        setValue(parentId, val);        id = parentId;    }}

比如节点2048被分配出去,更新过程如下:

到目前为止,基于poolChunk的节点分配已经完成。

上述就是小编为大家分享的如何理解Netty内存管理 PoolChunk了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注行业资讯频道。

节点 分配 内存 管理 大小 更新 手动 方法 分析 位置 使用方法 内容 多年 情况 数组 深度 程序 程序员 保证 合适 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技小额贷款 江苏南京365互联网科技 阿里巴巴算科技企业还是互联网 阿里互联网科技公司 宁夏众和广鑫互联网科技有限公司 荆州市昕露互联网络科技有限公司 花神(南京)互联网科技有限公司 湖南一路畅行互联网科技 呼和浩特新华互联网科技学院 链环科技传统企业怎么转型互联网 互联网科技和信息 广西互联网科技孵化中心 华夏恒生科技与互联网科技 华中科技大学互联网的牛人 有人说阿里系是互联网科技企业 北京天晋互联网科技有限公司 互联网科技品牌 现代互联网科技公司 平安好医生打造互联网科技医疗 安徽九吞吴互联网科技有限公司 金融科技创新监管互联网金融 深圳互联网科技公司 新华互联网科技2019 互联网科技教育视频 知域互联网科技有限公司大骗子 乌鲁木齐新华智原互联网科技学校 皮皮虾互联网科技有限公司 中国科技和美国互联网 好易买互联网科技 中国主要互联网科技公司
0