属性
属性 含义 值 private static final int INTEGER_SIZE_MINUS_ONE 32-1 Integer.SIZE - 1 = 31 final PoolArena<T> arena 所属的区域 final T memory
申请的内存,根据HAS_UNSAFE的结果可分为ByteBuffer和byte[] final boolean unpooled 未池化 默认false final int offset
偏移量 默认为0 private final byte[] memoryMap
堆(完整平衡二叉树)
高为12(0 - 11) 所以长度为 1 << 12 = 4096
每个叶子节点代表8K的大小
根节点是byte[1]
数组中每个元素的值是节点的高 byte[1] = 0 byte[2]=byte[3]=1
若数组中某个元素的值=12 则这个元素对应的节点所代表的内存已被分配
下标为index的节点 对应左孩子的下标为 index*2次方 右孩子的下标为index*2+1
注意memoryMap是从下标1的位置开始的
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 ++;
}
}
private final byte[] depthMap
堆(完整平衡二叉树)
高为12(0 - 11) 所以长度为 1 << 12 = 4096
每个叶子节点代表8K的大小
根节点是byte[1]
数组中每个元素的值是节点的高 byte[1] = 0 byte[2]=byte[3]=1
下标为index的节点 对应左孩子的下标为 index*2次方 右孩子的下标为index*2+1
注意depthMap是从下标1的位置开始的
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 ++;
}
}
private final PoolSubpage<T>[] subpages
这里的PoolSubpage相当于页的概念
每个PoolSubpage的大小为8K
subpages的长度为1 << 11 = 2048个
subpages = new PoolSubpage[maxSubpageAllocs]
private final int subpageOverflowMask
子页面溢出掩码
主要作用是判断某个size是否小于pageSize
如果size & subpageOverflowMask == 0 那么 size小于pageSize
~(pageSize - 1)
private final int pageSize
页大小 8192 private final int pageShifts
页位移 13 private final int maxOrder
指数 11
private final int chunkSize
chunk大小 16M
private final int log2ChunkSize
chunkSize的幂数 24 (11+13) private final int maxSubpageAllocs
1 << 11 也就是2048
private final byte unusable
标明chunk中的某个节点(memoryMap中的节点)是否可用 (byte) (maxOrder + 1) 也就是12
private final Deque<ByteBuffer> cachedNioBuffers
用作从内存创建的ByteBuffer的缓存。
这些只是重复项,因此也只是内存本身周围的一个容器。
这些通常是PooledByteBuf中的操作所需的,因此可能会产生额外的GC,可以通过缓存重复项来大大减少GC。
2048
private int freeBytes
可用内存大小 默认为chunkSize
PoolChunkList<T> parent
所属PoolChunkList
PoolChunk<T> prev
PoolChunk<T> next
构造方法
PoolChunk(PoolArena<T> arena, T memory, int pageSize, int maxOrder, int pageShifts, int chunkSize, int offset) { unpooled = false; this.arena = arena; this.memory = memory; this.pageSize = pageSize; this.pageShifts = pageShifts; this.maxOrder = maxOrder; this.chunkSize = chunkSize; this.offset = offset; unusable = (byte) (maxOrder + 1); log2ChunkSize = log2(chunkSize); subpageOverflowMask = ~(pageSize - 1); freeBytes = chunkSize; assert maxOrder < 30 : "maxOrder should be < 30, but is: " + maxOrder; maxSubpageAllocs = 1 << maxOrder; // Generate the memory map. 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 ++; } } subpages = newSubpageArray(maxSubpageAllocs); cachedNioBuffers = new ArrayDeque<ByteBuffer>(8); }
PoolChunk(PoolArena<T> arena, T memory, int size, int offset) { unpooled = true; this.arena = arena; this.memory = memory; this.offset = offset; memoryMap = null; depthMap = null; subpages = null; subpageOverflowMask = 0; pageSize = 0; pageShifts = 0; maxOrder = 0; unusable = (byte) (maxOrder + 1); chunkSize = size; log2ChunkSize = log2(chunkSize); maxSubpageAllocs = 0; cachedNioBuffers = null; }