这样下次就不需要再去申请空闲页了,直接去池中找就好了 。Netty 中有 36 种 PoolSubpage,所以用 36 个 PoolSubpage 链表表示 PoolSubpage 池 。
因为单个 PoolChunk 只有 16M,这远远不够用,所以会很很多很多 PoolChunk,这些 PoolChunk 组成一个链表,然后用 PoolChunkList 持有这个链表 。
我们先从内存分配器 PoolArena 来分析 Netty 中的内存是如何分配的,Area 的工作就是从一整块内存中协调如何分配合适大小的内存给当前数据使用 。
PoolArena 是 Netty 的内存池实现抽象类,其内部子类为 HeapArena 和 DirectArena 。
HeapArena 对应堆内存(heap buffer),DirectArena 对应堆外直接内存(direct buffer),两者除了操作的内存(byte[] 和 ByteBuffer)不同外其余完全一致 。
从结构上来看,PoolArena 中主要包含三部分子内存池:
- tinySubpagePools
- smallSubpagePools
- 一系列的 PoolChunkList
PoolChunkList 是一个容器,其内部可以保存一系列的 PoolChunk 对象,并且,Netty 会根据内存使用率的不同,将 PoolChunkList 分为不同等级的容器 。
abstract class PoolArena<T> implements PoolArenaMetric { enum SizeClass { Tiny, Small, Normal } // 该参数指定了tinySubpagePools数组的长度,由于tinySubpagePools每一个元素的内存块差值为16, // 因而数组长度是512/16,也即这里的512 >>> 4 static final int numTinySubpagePools = 512 >>> 4; //表示该PoolArena的allocator final PooledByteBufAllocator parent; //表示PoolChunk中由Page节点构成的二叉树的最大高度,默认11 private final int maxOrder; //page的大小,默认8K final int pageSize; // 指定了叶节点大小8KB是2的多少次幂,默认为13,该字段的主要作用是,在计算目标内存属于二叉树的 // 第几层的时候,可以借助于其内存大小相对于pageShifts的差值,从而快速计算其所在层数 final int pageShifts; //默认16MB final int chunkSize; // 由于PoolSubpage的大小为8KB=8196,因而该字段的值为 // -8192=>=> 1111 1111 1111 1111 1110 0000 0000 0000 // 这样在判断目标内存是否小于8KB时,只需要将目标内存与该数字进行与操作,只要操作结果等于0, // 就说明目标内存是小于8KB的,这样就可以判断其是应该首先在tinySubpagePools或smallSubpagePools // 中进行内存申请 final int subpageOverflowMask; // 该参数指定了smallSubpagePools数组的长度,默认为4 final int numSmallSubpagePools; //tinySubpagePools用来分配小于512 byte的Page private final PoolSubpage<T>[] tinySubpagePools; //smallSubpagePools用来分配大于等于512 byte且小于pageSize内存的Page private final PoolSubpage<T>[] smallSubpagePools; //用来存储用来分配给大于等于pageSize大小内存的PoolChunk //存储内存利用率50-100%的chunk private final PoolChunkList<T> q050; //存储内存利用率25-75%的chunk private final PoolChunkList<T> q025; //存储内存利用率1-50%的chunk private final PoolChunkList<T> q000; //存储内存利用率0-25%的chunk private final PoolChunkList<T> qInit; //存储内存利用率75-100%的chunk private final PoolChunkList<T> q075; //存储内存利用率100%的chunk private final PoolChunkList<T> q100; //堆内存(heap buffer) static final class HeapArena extends PoolArena<byte[]> { } //堆外直接内存(direct buffer) static final class DirectArena extends PoolArena<ByteBuffer> { }}如上所示,PoolArena 是由多个 PoolChunk 组成的大块内存区域,而每个 PoolChunk 则由多个 Page 组成 。
推荐阅读
- 大学|高中生为什么要拼尽全力考入名校?这是我见到最好的答案
- 解冻淘宝店铺保证金需要把店铺商品下架吗 淘宝店被彻底释放了保证金怎么办?
- 生意参谋页面很多我想最快了解某一个指标 生意参谋商城点击占比在哪里
- 淘宝网店运营方案 淘宝运营方案策划
- 手机如何找回原来开的淘宝店铺 淘宝店铺被彻底释放后信誉还有吗
- 淘宝店铺推广方式 如何做淘宝推广
- 淘宝生意参谋怎么看同行转化率 阿里巴巴生意参谋怎么看同行数据
- 呈贡蒲门茶品鉴地,我们持盅看茶
- 怎么弄封别人的淘宝店 淘宝店铺被彻底释放了怎么办
- 淘宝卖家中心的体检中心在哪里 淘宝的体检中心在哪
