/** * 创建tiny规格的MemoryRegionCache * cacheSize: 单位缓存的大小,默认512字节 * numCaches: 创建cache数组的数量,默认32 */ privatestatic <T> MemoryRegionCache<T>[] createSubPageCaches( int cacheSize, int numCaches, SizeClass sizeClass) { if (cacheSize > 0 && numCaches > 0) { @SuppressWarnings("unchecked") MemoryRegionCache<T>[] cache = new MemoryRegionCache[numCaches]; for (int i = 0; i < cache.length; i++) { // TODO: maybe use cacheSize / cache.length cache[i] = new SubPageMemoryRegionCache<T>(cacheSize, sizeClass); } return cache; } else { returnnull; } }
2.2 将相应的PoolChunk和handle信息添加到缓存,方便下次取出
MemoryRegionCache#add(PoolChunk<T> chunk, long handle)
1 2 3 4 5 6 7 8 9 10 11 12
publicfinalbooleanadd(PoolChunk<T> chunk, long handle){ //2.2.1 创建Entry对象并添加到queue里 Entry<T> entry = newEntry(chunk, handle); boolean queued = queue.offer(entry); //2.2.2 如果加入queue失败 if (!queued) { // If it was not possible to cache the chunk, immediately recycle the entry entry.recycle(); }
return queued; }
首先,我们看看PoolThreadCache$Entry结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
staticfinalclassEntry<T> { final Handle<Entry<?>> recyclerHandle;//回收handle PoolChunk<T> chunk;//具体某一块内存 long handle = -1;//chunk+handle:指向某一块内存的位置,handle是一个相对地址
voidfreeChunk(PoolChunk<T> chunk, long handle, SizeClass sizeClass){ finalboolean destroyChunk; synchronized (this) { switch (sizeClass) { case Normal: //统计normal规格的释放数量 ++deallocationsNormal; break; case Small: ++deallocationsSmall; break; case Tiny: ++deallocationsTiny; break; default: thrownew Error(); } //1.3.1 根据不同的规格释放在chunk上指向的内存 destroyChunk = !chunk.parent.free(chunk, handle); } //1.3.2 通过调用UNSAFE的本地方法,清理内存 if (destroyChunk) { // destroyChunk not need to be called while holding the synchronized lock. destroyChunk(chunk); } }
booleanfree(PoolChunk<T> chunk, long handle){ chunk.free(handle); if (chunk.usage() < minUsage) { remove(chunk); // Move the PoolChunk down the PoolChunkList linked-list. return move0(chunk); } returntrue; }
voidfree(long handle){ int memoryMapIdx = memoryMapIdx(handle); int bitmapIdx = bitmapIdx(handle); //根据handle来释放page if (bitmapIdx != 0) { // free a subpage PoolSubpage<T> subpage = subpages[subpageIdx(memoryMapIdx)]; assert subpage != null && subpage.doNotDestroy;
// Obtain the head of the PoolSubPage pool that is owned by the PoolArena and synchronize on it. // This is need as we may add it back and so alter the linked-list structure. //找到包含头节点的PoolSubpage PoolSubpage<T> head = arena.findSubpagePoolHead(subpage.elemSize); synchronized (head) { //同步将这个位视图的置为0 if (subpage.free(head, bitmapIdx & 0x3FFFFFFF)) { return; } } } freeBytes += runLength(memoryMapIdx); setValue(memoryMapIdx, depth(memoryMapIdx)); updateParentsFree(memoryMapIdx); }