Netty内存管理
PoolChunk
作用: 8K - 16M范围的内存分配,分配容量为PageSize的整数倍,PageSize默认为8K;
基本概念
- maxOrder:二叉树的最大深度;
- chunkSize:PoolChunk的容量,默认为16M,即根节点的可分配容量;
chunkSize = PageSize * 2^maxOrder
内存管理
Page是PoolChunk内存管理的基本单元,PoolChunk通过完全二叉树的方式管理内存,如下图所示,每个节点的可分配内存为其包含的叶子节点内存之和,内存分配过程如下:
- 首先定位请求内存大小在二叉树中的深度;
- 然后从左到右依次寻找满足条件的节点;
Netty使用数组存储完全二叉树,数组的下标对应节点的编号,数组的内容为当前节点的可用内存在二叉树中的深度,用x表示,通过x的消息判断内存使用情况:
- x == depth_of_i,表示内存还未使用,当前节点及其所有子节点都可以用来分配;
- depth_of_i < x <= maxOrder, 表示内存部分使用,在x层的子节点中有可分配的内存;
- x == maxOrder + 1,表示无可用内存;
PoolSubPage
作用: 0 - 8K范围的内存分配,当请求内存大小小于PageSize时,精细化管理内存,提升内存使用率,减小内存碎片;
分配过程:
- 首先,从PoolChunk申请一个空闲Page;
- 然后,按照elemSize将Page等分成若干份,用bitmap表示每份的使用情况(0未使用,1已使用);
PoolArena
PoolArena是内存管理的核心,为了能够合理分配内存,减少内存碎片,PoolArena对内存进行了精细划分,按照请求内存大小可以分为三类:tiny、small、和normal。0-512B范围属于tiny,特点是:从16B开始,每次增加16B,共32个;512B - 4K范围属于small,特点是从1024B开始,每次翻倍,共4个;8K - 16M属于normal范围,基本管理单元是8K,通过二叉树形式管理,如下图所示:
参考