php移动网站开发桃源网站建设
一、规格化
内存池类似于一个内存零售商, 从操作系统中申请一整块内存, 然后对其进行合理分割, 将分割后的小内存返回给程序。这里存在3个尺寸:
- 分割尺寸: 底层内存管理的基本单位, 比如常见的以页为单位分配, 但是页的大小是灵活的;
- 申请尺寸: 内存使用者希望申请到的内存大小;
- 分配尺寸: 内存池实际分配的内存大小, 存在该尺寸的原因是分配尺寸>=申请尺寸;
总结来说, 内存规格化就是确定有哪些尺寸的内存, 针对不同的申请尺寸提供对应的分配尺寸。
二、规格化描述7元组
每一种尺寸使用下面的7元组表示| 元组字段以及含义如下
| name | 代码注释 | 个人理解 |
|---|---|---|
| index | Size class index | 从0开始的索引 |
| log2Group | Log of group base size (no deltas added) | 尺寸分组的base |
| log2Delta | Log of delta to previous size class | 分组内的增量单位 |
| nDelta | Delta multiplier | 分组内增量单位的倍数 |
| isMultiPageSize | ‘yes’ if a multiple of the page size ‘no’ otherwise | 是否为Page的整倍数 |
| isSubPage | ‘yes’ if a subpage size class ‘no’ otherwise. | 是否可能为SubPage |
| log2DeltaLookup | Same as log2Delta if a lookup table size class ‘no’ otherwise. | 代码中没有使用 |
三、规格化结果
| index | log2Group | log2Delta | nDelta | isMultiPageSize | isSubPage | log2DeltaLookup | size |
|---|---|---|---|---|---|---|---|
| 0 | 4 | 4 | 0 | 0 | 1 | 4 | 16 |
| 1 | 4 | 4 | 1 | 0 | 1 | 4 | 32 |
| 2 | 4 | 4 | 2 | 0 | 1 | 4 | 48 |
| 3 | 4 | 4 | 3 | 0 | 1 | 4 | 64 |
| 4 | 6 | 4 | 1 | 0 | 1 | 4 | 80 |
| 5 | 6 | 4 | 2 | 0 | 1 | 4 | 96 |
| 6 | 6 | 4 | 3 | 0 | 1 | 4 | 112 |
| 7 | 6 | 4 | 4 | 0 | 1 | 4 | 128 |
| 8 | 7 | 5 | 1 | 0 | 1 | 5 | 160 |
| 9 | 7 | 5 | 2 | 0 | 1 | 5 | 192 |
| 10 | 7 | 5 | 3 | 0 | 1 | 5 | 224 |
| 11 | 7 | 5 | 4 | 0 | 1 | 5 | 256 |
| 12 | 8 | 6 | 1 | 0 | 1 | 6 | 320 |
| 13 | 8 | 6 | 2 | 0 | 1 | 6 | 384 |
| 14 | 8 | 6 | 3 | 0 | 1 | 6 | 448 |
| 15 | 8 | 6 | 4 | 0 | 1 | 6 | 512 |
| 16 | 9 | 7 | 1 | 0 | 1 | 7 | 640 |
| 17 | 9 | 7 | 2 | 0 | 1 | 7 | 768 |
| 18 | 9 | 7 | 3 | 0 | 1 | 7 | 896 |
| 19 | 9 | 7 | 4 | 0 | 1 | 7 | 1024 |
| 20 | 10 | 8 | 1 | 0 | 1 | 8 | 1280 |
| 21 | 10 | 8 | 2 | 0 | 1 | 8 | 1536 |
| 22 | 10 | 8 | 3 | 0 | 1 | 8 | 1792 |
| 23 | 10 | 8 | 4 | 0 | 1 | 8 | 2048 |
| 24 | 11 | 9 | 1 | 0 | 1 | 9 | 2560 |
| 25 | 11 | 9 | 2 | 0 | 1 | 9 | 3072 |
| 26 | 11 | 9 | 3 | 0 | 1 | 9 | 3584 |
| 27 | 11 | 9 | 4 | 0 | 1 | 9 | 4096 |
| 28 | 12 | 10 | 1 | 0 | 1 | 0 | 5120 |
| 29 | 12 | 10 | 2 | 0 | 1 | 0 | 6144 |
| 30 | 12 | 10 | 3 | 0 | 1 | 0 | 7168 |
| 31 | 12 | 10 | 4 | 1 | 1 | 0 | 8192 |
| 32 | 13 | 11 | 1 | 0 | 1 | 0 | 10240 |
| 33 | 13 | 11 | 2 | 0 | 1 | 0 | 12288 |
| 34 | 13 | 11 | 3 | 0 | 1 | 0 | 14336 |
| 35 | 13 | 11 | 4 | 1 | 1 | 0 | 16384 |
| 36 | 14 | 12 | 1 | 0 | 1 | 0 | 20480 |
| 37 | 14 | 12 | 2 | 1 | 1 | 0 | 24576 |
| 38 | 14 | 12 | 3 | 0 | 1 | 0 | 28672 |
| 39 | 14 | 12 | 4 | 1 | 0 | 0 | 32768 |
| 40 | 15 | 13 | 1 | 1 | 0 | 0 | 40960 |
| 41 | 15 | 13 | 2 | 1 | 0 | 0 | 49152 |
| 42 | 15 | 13 | 3 | 1 | 0 | 0 | 57344 |
| 43 | 15 | 13 | 4 | 1 | 0 | 0 | 65536 |
| 44 | 16 | 14 | 1 | 1 | 0 | 0 | 81920 |
| 45 | 16 | 14 | 2 | 1 | 0 | 0 | 98304 |
| 46 | 16 | 14 | 3 | 1 | 0 | 0 | 114688 |
| 47 | 16 | 14 | 4 | 1 | 0 | 0 | 131072 |
| 48 | 17 | 15 | 1 | 1 | 0 | 0 | 163840 |
| 49 | 17 | 15 | 2 | 1 | 0 | 0 | 196608 |
| 50 | 17 | 15 | 3 | 1 | 0 | 0 | 229376 |
| 51 | 17 | 15 | 4 | 1 | 0 | 0 | 262144 |
| 52 | 18 | 16 | 1 | 1 | 0 | 0 | 327680 |
| 53 | 18 | 16 | 2 | 1 | 0 | 0 | 393216 |
| 54 | 18 | 16 | 3 | 1 | 0 | 0 | 458752 |
| 55 | 18 | 16 | 4 | 1 | 0 | 0 | 524288 |
| 56 | 19 | 17 | 1 | 1 | 0 | 0 | 655360 |
| 57 | 19 | 17 | 2 | 1 | 0 | 0 | 786432 |
| 58 | 19 | 17 | 3 | 1 | 0 | 0 | 917504 |
| 59 | 19 | 17 | 4 | 1 | 0 | 0 | 1048576 |
| 60 | 20 | 18 | 1 | 1 | 0 | 0 | 1310720 |
| 61 | 20 | 18 | 2 | 1 | 0 | 0 | 1572864 |
| 62 | 20 | 18 | 3 | 1 | 0 | 0 | 1835008 |
| 63 | 20 | 18 | 4 | 1 | 0 | 0 | 2097152 |
| 64 | 21 | 19 | 1 | 1 | 0 | 0 | 2621440 |
| 65 | 21 | 19 | 2 | 1 | 0 | 0 | 3145728 |
| 66 | 21 | 19 | 3 | 1 | 0 | 0 | 3670016 |
| 67 | 21 | 19 | 4 | 1 | 0 | 0 | 4194304 |
| 68 | 22 | 20 | 1 | 1 | 0 | 0 | 5242880 |
| 69 | 22 | 20 | 2 | 1 | 0 | 0 | 6291456 |
| 70 | 22 | 20 | 3 | 1 | 0 | 0 | 7340032 |
| 71 | 22 | 20 | 4 | 1 | 0 | 0 | 8388608 |
| 72 | 23 | 21 | 1 | 1 | 0 | 0 | 10485760 |
| 73 | 23 | 21 | 2 | 1 | 0 | 0 | 12582912 |
| 74 | 23 | 21 | 3 | 1 | 0 | 0 | 14680064 |
| 75 | 23 | 21 | 4 | 1 | 0 | 0 | 16777216 |
四、相关计算公式
a. 每个内存规格的尺寸计算公式
size = (1 << log2Group) + (1 << log2Delta) * nDelta;
b. 第0组是单独初始化不予考虑, 从第1组开始
log2Group = log2Delta + 2;
c. 通过a,b合并得到
size = 2 ^ log2Delta (4 + nDelta)
d. 从c得到, 自第1组开始组内每个内存大小是logDelta的[ 5,6,7,8 ]倍;
五、结果说明
- 最小尺寸16B, 最大尺寸16M;
- 尺寸分19组, 每组4个, 共76种尺寸(规格, 颗粒度);
- 从第1组开始, 后一组是前一组容量的2倍;
- 组内后一个是在前一个的尺寸基础上+log2Delta;
- 尺寸>=pageSize(8K)的有40个;
- 尺寸小于pageSize(8K)的有36个;
- 这种尺寸作为分配的最小颗粒度, 同时也影响了做实际分配时的空间大小以及对应的最小颗粒度(元素)数量;
六、小结
本篇介绍的是Netty4.1.73-Final的内存规格化, 后续的内存分配均以该内存规格为基础进行。整个尺寸要覆盖小尺寸和大尺寸, 平衡分配效率和空间利用率。这里仅仅介绍了其内存规格化的实现结果, 如此设计的原因和历史的演进, 感兴趣的小伙伴可以去进一步研究Jmelloc项目。
