属性
属性 含义 值 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 chunkSizechunk大小 16M
private final int log2ChunkSizechunkSize的幂数 24 (11+13) private final int maxSubpageAllocs1 << 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; }
520

被折叠的 条评论
为什么被折叠?



