Package io.netty.buffer
Class PoolChunk<T>
- java.lang.Object
-
- io.netty.buffer.PoolChunk<T>
-
- All Implemented Interfaces:
PoolChunkMetric
final class PoolChunk<T> extends java.lang.Object implements PoolChunkMetric
Description of algorithm for PageRun/PoolSubpage allocation from PoolChunk Notation: The following terms are important to understand the code > page - a page is the smallest unit of memory chunk that can be allocated > run - a run is a collection of pages > chunk - a chunk is a collection of runs > in this code chunkSize = maxPages * pageSize To begin we allocate a byte array of size = chunkSize Whenever a ByteBuf of given size needs to be created we search for the first position in the byte array that has enough empty space to accommodate the requested size and return a (long) handle that encodes this offset information, (this memory segment is then marked as reserved so it is always used by exactly one ByteBuf and no more) For simplicity all sizes are normalized according to {@link PoolArena#sizeClass#size2SizeIdx(int)} method. This ensures that when we request for memory segments of size > pageSize the normalizedCapacity equals the next nearest size inSizeClasses. A chunk has the following layout: /-----------------\ | run | | | | | |-----------------| | run | | | |-----------------| | unalloctated | | (freed) | | | |-----------------| | subpage | |-----------------| | unallocated | | (freed) | | ... | | ... | | ... | | | | | | | \-----------------/ handle: ------- a handle is a long number, the bit layout of a run looks like: oooooooo ooooooos ssssssss ssssssue bbbbbbbb bbbbbbbb bbbbbbbb bbbbbbbb o: runOffset (page offset in the chunk), 15bit s: size (number of pages) of this run, 15bit u: isUsed?, 1bit e: isSubpage?, 1bit b: bitmapIdx of subpage, zero if it's not subpage, 32bit runsAvailMap: ------ a map which manages all runs (used and not in used). For each run, the first runOffset and last runOffset are stored in runsAvailMap. key: runOffset value: handle runsAvail: ---------- an array ofPriorityQueue. Each queue manages same size of runs. Runs are sorted by offset, so that we always allocate runs with smaller offset. Algorithm: ---------- As we allocate runs, we update values stored in runsAvailMap and runsAvail so that the property is maintained. Initialization - In the beginning we store the initial run which is the whole chunk. The initial run: runOffset = 0 size = chunkSize isUsed = no isSubpage = no bitmapIdx = 0 Algorithm: [allocateRun(size)] ---------- 1) find the first avail run using in runsAvails according to size 2) if pages of run is larger than request pages then split it, and save the tailing run for later using Algorithm: [allocateSubpage(size)] ---------- 1) find a not full subpage according to size. if it already exists just return, otherwise allocate a new PoolSubpage and call init() note that this subpage object is added to subpagesPool in the PoolArena when we init() it 2) call subpage.allocate() Algorithm: [free(handle, length, nioBuffer)] ---------- 1) if it is a subpage, return the slab back into this subpage 2) if the subpage is not used or it is a run, then start free this run 3) merge continuous avail runs 4) save the merged run
-
-
Field Summary
Fields Modifier and Type Field Description (package private) PoolArena<T>arena(package private) java.lang.Objectbaseprivate static intBITMAP_IDX_BIT_LENGTHprivate java.util.Deque<java.nio.ByteBuffer>cachedNioBuffers(package private) intchunkSize(package private) intfreeBytesprivate static intINUSED_BIT_LENGTH(package private) static intIS_SUBPAGE_SHIFT(package private) static intIS_USED_SHIFT(package private) intmaxPageIdx(package private) Tmemory(package private) PoolChunk<T>next(package private) intpageShifts(package private) intpageSize(package private) PoolChunkList<T>parentprivate LongCounterpinnedBytesAccounting of pinned memory – memory that is currently in use by ByteBuf instances.(package private) PoolChunk<T>prev(package private) static intRUN_OFFSET_SHIFTprivate IntPriorityQueue[]runsAvailmanage all avail runsprivate java.util.concurrent.locks.ReentrantLockrunsAvailLockprivate LongLongHashMaprunsAvailMapstore the first page and last page of each avail runprivate static intSIZE_BIT_LENGTH(package private) static intSIZE_SHIFTprivate static intSUBPAGE_BIT_LENGTHprivate PoolSubpage<T>[]subpagesmanage all subpages in this chunk(package private) booleanunpooled
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description (package private) booleanallocate(PooledByteBuf<T> buf, int reqCapacity, int sizeIdx, PoolThreadCache cache)private longallocateRun(int runSize)private longallocateSubpage(int sizeIdx, PoolSubpage<T> head)Create / initialize a new PoolSubpage of normCapacity.(package private) static intbitmapIdx(long handle)private intcalculateRunSize(int sizeIdx)intchunkSize()Return the size of the chunk in bytes, this is the maximum of bytes that can be served out of the chunk.private longcollapseNext(long handle)private longcollapsePast(long handle)private longcollapseRuns(long handle)(package private) voiddecrementPinnedMemory(int delta)(package private) voiddestroy()(package private) voidfree(long handle, int normCapacity, java.nio.ByteBuffer 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.intfreeBytes()Return the number of free bytes in the chunk.private longgetAvailRunByOffset(int runOffset)(package private) voidincrementPinnedMemory(int delta)(package private) voidinitBuf(PooledByteBuf<T> buf, java.nio.ByteBuffer nioBuffer, long handle, int reqCapacity, PoolThreadCache threadCache)(package private) voidinitBufWithSubpage(PooledByteBuf<T> buf, java.nio.ByteBuffer nioBuffer, long handle, int reqCapacity, PoolThreadCache threadCache)private voidinsertAvailRun(int runOffset, int pages, long handle)private voidinsertAvailRun0(int runOffset, long handle)(package private) static booleanisRun(long handle)(package private) static booleanisSubpage(long handle)(package private) static booleanisUsed(long handle)private static intlastPage(int runOffset, int pages)private static IntPriorityQueue[]newRunsAvailqueueArray(int size)intpinnedBytes()private voidremoveAvailRun(long handle)private voidremoveAvailRun0(long handle)private intrunFirstBestFit(int pageIdx)(package private) static intrunOffset(long handle)(package private) static intrunPages(long handle)(package private) static intrunSize(int pageShifts, long handle)private longsplitLargeRun(long handle, int needPages)private static longtoRunHandle(int runOffset, int runPages, int inUsed)java.lang.StringtoString()intusage()Return the percentage of the current usage of the chunk.private intusage(int freeBytes)
-
-
-
Field Detail
-
SIZE_BIT_LENGTH
private static final int SIZE_BIT_LENGTH
- See Also:
- Constant Field Values
-
INUSED_BIT_LENGTH
private static final int INUSED_BIT_LENGTH
- See Also:
- Constant Field Values
-
SUBPAGE_BIT_LENGTH
private static final int SUBPAGE_BIT_LENGTH
- See Also:
- Constant Field Values
-
BITMAP_IDX_BIT_LENGTH
private static final int BITMAP_IDX_BIT_LENGTH
- See Also:
- Constant Field Values
-
IS_SUBPAGE_SHIFT
static final int IS_SUBPAGE_SHIFT
- See Also:
- Constant Field Values
-
IS_USED_SHIFT
static final int IS_USED_SHIFT
- See Also:
- Constant Field Values
-
SIZE_SHIFT
static final int SIZE_SHIFT
- See Also:
- Constant Field Values
-
RUN_OFFSET_SHIFT
static final int RUN_OFFSET_SHIFT
- See Also:
- Constant Field Values
-
base
final java.lang.Object base
-
memory
final T memory
-
unpooled
final boolean unpooled
-
runsAvailMap
private final LongLongHashMap runsAvailMap
store the first page and last page of each avail run
-
runsAvail
private final IntPriorityQueue[] runsAvail
manage all avail runs
-
runsAvailLock
private final java.util.concurrent.locks.ReentrantLock runsAvailLock
-
subpages
private final PoolSubpage<T>[] subpages
manage all subpages in this chunk
-
pinnedBytes
private final LongCounter pinnedBytes
Accounting of pinned memory – memory that is currently in use by ByteBuf instances.
-
pageSize
final int pageSize
-
pageShifts
final int pageShifts
-
chunkSize
final int chunkSize
-
maxPageIdx
final int maxPageIdx
-
cachedNioBuffers
private final java.util.Deque<java.nio.ByteBuffer> cachedNioBuffers
-
freeBytes
int freeBytes
-
parent
PoolChunkList<T> parent
-
-
Method Detail
-
newRunsAvailqueueArray
private static IntPriorityQueue[] newRunsAvailqueueArray(int size)
-
insertAvailRun
private void insertAvailRun(int runOffset, int pages, long handle)
-
insertAvailRun0
private void insertAvailRun0(int runOffset, long handle)
-
removeAvailRun
private void removeAvailRun(long handle)
-
removeAvailRun0
private void removeAvailRun0(long handle)
-
lastPage
private static int lastPage(int runOffset, int pages)
-
getAvailRunByOffset
private long getAvailRunByOffset(int runOffset)
-
usage
public int usage()
Description copied from interface:PoolChunkMetricReturn the percentage of the current usage of the chunk.- Specified by:
usagein interfacePoolChunkMetric
-
usage
private int usage(int freeBytes)
-
allocate
boolean allocate(PooledByteBuf<T> buf, int reqCapacity, int sizeIdx, PoolThreadCache cache)
-
allocateRun
private long allocateRun(int runSize)
-
calculateRunSize
private int calculateRunSize(int sizeIdx)
-
runFirstBestFit
private int runFirstBestFit(int pageIdx)
-
splitLargeRun
private long splitLargeRun(long handle, int needPages)
-
allocateSubpage
private long allocateSubpage(int sizeIdx, PoolSubpage<T> head)Create / initialize a new PoolSubpage of normCapacity. Any PoolSubpage created / initialized here is added to subpage pool in the PoolArena that owns this PoolChunk.- Parameters:
sizeIdx- sizeIdx of normalized sizehead- head of subpages- Returns:
- index in memoryMap
-
free
void free(long handle, int normCapacity, java.nio.ByteBuffer 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- Parameters:
handle- handle to free
-
collapseRuns
private long collapseRuns(long handle)
-
collapsePast
private long collapsePast(long handle)
-
collapseNext
private long collapseNext(long handle)
-
toRunHandle
private static long toRunHandle(int runOffset, int runPages, int inUsed)
-
initBuf
void initBuf(PooledByteBuf<T> buf, java.nio.ByteBuffer nioBuffer, long handle, int reqCapacity, PoolThreadCache threadCache)
-
initBufWithSubpage
void initBufWithSubpage(PooledByteBuf<T> buf, java.nio.ByteBuffer nioBuffer, long handle, int reqCapacity, PoolThreadCache threadCache)
-
incrementPinnedMemory
void incrementPinnedMemory(int delta)
-
decrementPinnedMemory
void decrementPinnedMemory(int delta)
-
chunkSize
public int chunkSize()
Description copied from interface:PoolChunkMetricReturn the size of the chunk in bytes, this is the maximum of bytes that can be served out of the chunk.- Specified by:
chunkSizein interfacePoolChunkMetric
-
freeBytes
public int freeBytes()
Description copied from interface:PoolChunkMetricReturn the number of free bytes in the chunk.- Specified by:
freeBytesin interfacePoolChunkMetric
-
pinnedBytes
public int pinnedBytes()
-
toString
public java.lang.String toString()
- Overrides:
toStringin classjava.lang.Object
-
destroy
void destroy()
-
runOffset
static int runOffset(long handle)
-
runSize
static int runSize(int pageShifts, long handle)
-
runPages
static int runPages(long handle)
-
isUsed
static boolean isUsed(long handle)
-
isRun
static boolean isRun(long handle)
-
isSubpage
static boolean isSubpage(long handle)
-
bitmapIdx
static int bitmapIdx(long handle)
-
-