Class BufferPool
java.lang.Object
org.apache.cassandra.utils.memory.BufferPool
A pool of ByteBuffers that can be recycled to reduce system direct memory fragmentation and improve buffer allocation
performance.
Each
BufferPool instance has one BufferPool.GlobalPool which allocates two kinds of chunks:
- Macro Chunk
- A memory slab that has size of MACRO_CHUNK_SIZE which is 64 * NORMAL_CHUNK_SIZE
- Used to allocate normal chunk with size of NORMAL_CHUNK_SIZE
- Normal Chunk
- Used by
BufferPool.LocalPoolto serve buffer allocation - Minimum allocation unit is NORMAL_CHUNK_SIZE / 64
- Used by
BufferPool.GlobalPool maintains two kinds of freed chunks, fully freed chunks where all buffers are released, and
partially freed chunks where some buffers are not released, eg. held by ChunkCache.
Partially freed chunks are used to improve cache utilization and have lower priority compared to fully freed chunks.
BufferPool.LocalPool is a thread local pool to serve buffer allocation requests. There are two kinds of local pool:
- Normal Pool:
- used to serve allocation size that is larger than half of NORMAL_ALLOCATION_UNIT but less than NORMAL_CHUNK_SIZE
- when there is insufficient space in the local queue, it will request global pool for more normal chunks
- when normal chunk is recycled either fully or partially, it will be passed to global pool to be used by other pools
- Tiny Pool:
- used to serve allocation size that is less than NORMAL_ALLOCATION_UNIT
- when there is insufficient space in the local queue, it will request parent normal pool for more tiny chunks
- when tiny chunk is fully freed, it will be passed to paretn normal pool and corresponding buffer in the parent normal chunk is freed
new acquire release recycle
────────→ in GlobalPool ──────────────→ in LocalPool ──────────────→ EVICTED ──────────────────┐
owner = null owner = LocalPool owner = null │
status = IN_USE status = IN_USE status = EVICTED │
ready serves get / free serves free only │
↑ │
└────────────────────────────────────────────────────────────────────────────────┘
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic interfacefinal classA thread local class that grabs chunks from the global pool for this thread allocations. -
Field Summary
FieldsModifier and TypeFieldDescriptionprotected final BufferPoolMetricsprotected final Stringstatic final intstatic final intThe size of a page aligned buffer, 128KiBstatic final intstatic final intstatic final int -
Constructor Summary
ConstructorsConstructorDescriptionBufferPool(String name, long memoryUsageThreshold, boolean recyclePartially) -
Method Summary
Modifier and TypeMethodDescriptioncreate()voiddebug(org.apache.cassandra.utils.memory.BufferPool.Debug newDebug, BufferPool.DebugLeaks newDebugLeaks) get(int size, BufferType bufferType) getAtLeast(int size, BufferType bufferType) org.apache.cassandra.utils.memory.BufferPool.GlobalPoollongmetrics()longvoidput(ByteBuffer buffer) voidputUnusedPortion(ByteBuffer buffer) voidForces to recycle free local chunks back to the global pool.static introundUp(int size) static introundUp(int size, int unit) voidsetRecycleWhenFreeForCurrentThread(boolean recycleWhenFree) voidshutdownLocalCleaner(long timeout, TimeUnit unit) longtryGet(int size) Unlike the get methods, this will return null if the pool is exhaustedtryGetAtLeast(int size) voidThis is not thread safe and should only be used for unit testing.unwrapBufferPoolManagedBuffer(ByteBuffer originalBuffer) long
-
Field Details
-
NORMAL_CHUNK_SIZE
public static final int NORMAL_CHUNK_SIZEThe size of a page aligned buffer, 128KiB- See Also:
-
NORMAL_ALLOCATION_UNIT
public static final int NORMAL_ALLOCATION_UNIT- See Also:
-
TINY_CHUNK_SIZE
public static final int TINY_CHUNK_SIZE- See Also:
-
TINY_ALLOCATION_UNIT
public static final int TINY_ALLOCATION_UNIT- See Also:
-
TINY_ALLOCATION_LIMIT
public static final int TINY_ALLOCATION_LIMIT- See Also:
-
name
-
metrics
-
-
Constructor Details
-
BufferPool
-
-
Method Details
-
create
- Returns:
- a local pool instance and caller is responsible to release the pool
-
get
-
getAtLeast
-
tryGet
Unlike the get methods, this will return null if the pool is exhausted -
tryGetAtLeast
-
put
-
putUnusedPortion
-
setRecycleWhenFreeForCurrentThread
public void setRecycleWhenFreeForCurrentThread(boolean recycleWhenFree) -
sizeInBytes
public long sizeInBytes()- Returns:
- buffer size being allocated, including pooled buffers and unpooled buffers
-
usedSizeInBytes
public long usedSizeInBytes()- Returns:
- buffer size being used, including used pooled buffers and unpooled buffers
-
overflowMemoryInBytes
public long overflowMemoryInBytes()- Returns:
- unpooled buffer size being allocated outside of buffer pool.
-
memoryUsageThreshold
public long memoryUsageThreshold()- Returns:
- maximum pooled buffer size in bytes
-
globalPool
public org.apache.cassandra.utils.memory.BufferPool.GlobalPool globalPool() -
releaseLocal
public void releaseLocal()Forces to recycle free local chunks back to the global pool. This is needed because if buffers were freed by a different thread than the one that allocated them, recycling might not have happened and the local pool may still own some fully empty chunks. -
debug
public void debug(org.apache.cassandra.utils.memory.BufferPool.Debug newDebug, BufferPool.DebugLeaks newDebugLeaks) -
roundUp
public static int roundUp(int size) -
roundUp
public static int roundUp(int size, int unit) -
shutdownLocalCleaner
public void shutdownLocalCleaner(long timeout, TimeUnit unit) throws InterruptedException, TimeoutException - Throws:
InterruptedExceptionTimeoutException
-
metrics
-
unsafeReset
public void unsafeReset()This is not thread safe and should only be used for unit testing. -
unwrapBufferPoolManagedBuffer
- Returns:
- the inner buffer if it has a BufferPool.Chunk attached and originalBuffer in other cases
-