属性
属性 含义 值 final PoolChunk<T> chunk
所属chunk
private final int memoryMapIdx
在chunk的memoryMap数组中的下标 通过下标能确认在memoryMap这个堆的哪个节点
private final int runOffset
相对于chunk offset的偏移量 标明这个subPage用的是chunk的哪一块内存
private final int pageSize
页的大小 8192
private final long[] bitmap
位图数组 如果对一个位图取反==0 说明这个位图代表的64个element都被分配了 for (int i = 0; i < bitmapLength; i ++) { bitmap[i] = 0; }
PoolSubpage<T> prev
PoolSubpage<T> next
boolean doNotDestroy
不销毁 true
int elemSize
元素的大小 subPage会根据elemSize分成大小均等的数量
private int maxNumElems
最大元素数量 即 subPage根据elemSize分成大小均等的最大数量 maxNumElems = numAvail = pageSize / elemSize;
private int bitmapLength
bitmap数组的长度 //右移6位相当于除以64,因为bitmap是long类型的数组,而long是64位的,所以bitmap的一个位图可以表示64个element
bitmapLength = maxNumElems >>> 6;
//这里说明不能被64整除,所以+1
if ((maxNumElems & 63) != 0) {
bitmapLength ++;
}
private int nextAvail
下一个可用element的位置
private int numAvail
可用element的数量
构造方法
PoolSubpage(int pageSize) { chunk = null; memoryMapIdx = -1; runOffset = -1; elemSize = -1; this.pageSize = pageSize; bitmap = null; }
PoolSubpage(PoolSubpage<T> head, PoolChunk<T> chunk, int memoryMapIdx, int runOffset, int pageSize, int elemSize) { this.chunk = chunk; this.memoryMapIdx = memoryMapIdx; this.runOffset = runOffset; this.pageSize = pageSize; bitmap = new long[pageSize >>> 10]; // pageSize / 16 / 64 init(head, elemSize); } void init(PoolSubpage<T> head, int elemSize) { doNotDestroy = true; this.elemSize = elemSize; if (elemSize != 0) { //计算page能够分成多少个元素 maxNumElems = numAvail = pageSize / elemSize; nextAvail = 0; //bitmap数组中每个位图(元素)能够标明64个element(因为long有64位),所以这里除以64 bitmapLength = maxNumElems >>> 6; if ((maxNumElems & 63) != 0) { bitmapLength ++; } for (int i = 0; i < bitmapLength; i ++) { bitmap[i] = 0; } } addToPool(head); } private void addToPool(PoolSubpage<T> head) { assert prev == null && next == null; prev = head; next = head.next; next.prev = this; head.next = this; }