void free ( long handle , ByteBuffer nioBuffer ) { int memoryMapIdx = memoryMapIdx ( handle ) ; int bitmapIdx = bitmapIdx ( handle ) ; 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 < T > head = arena . findSubpagePoolHead ( subpage . elemSize ) ; synchronized ( head ) { if ( subpage . free ( head , bitmapIdx & 0x3FFFFFFF ) ) { return ; } } } freeBytes += runLength ( memoryMapIdx ) ; setValue ( memoryMapIdx , depth ( memoryMapIdx ) ) ; updateParentsFree ( memoryMapIdx ) ; if ( nioBuffer != null && cachedNioBuffers != null && cachedNioBuffers . size ( ) < PooledByteBufAllocator . DEFAULT_MAX_CACHED_BYTEBUFFERS_PER_CHUNK ) { cachedNioBuffers . offer ( nioBuffer ) ; } }
Free a subpage or a run of pages When a subpage is freed from PoolSubpage it might be added back to subpage pool of the owning PoolArena If the subpage pool in PoolArena has at least one other PoolSubpage of given elemSize we can completely free the owning Page so it is available for subsequent allocations