Class BufferPool
- java.lang.Object
-
- org.apache.cassandra.utils.memory.BufferPool
-
public class BufferPool extends java.lang.ObjectA pool of ByteBuffers that can be recycled to reduce system direct memory fragmentation and improve buffer allocation performance. EachBufferPoolinstance has oneBufferPool.GlobalPoolwhich 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.GlobalPoolmaintains 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 byChunkCache. Partially freed chunks are used to improve cache utilization and have lower priority compared to fully freed chunks.BufferPool.LocalPoolis 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 │ ↑ │ └────────────────────────────────────────────────────────────────────────────────┘ - Macro Chunk
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static interfaceBufferPool.DebugLeaksclassBufferPool.LocalPoolA thread local class that grabs chunks from the global pool for this thread allocations.
-
Field Summary
Fields Modifier and Type Field Description protected BufferPoolMetricsmetricsprotected java.lang.Stringnamestatic intNORMAL_ALLOCATION_UNITstatic intNORMAL_CHUNK_SIZEThe size of a page aligned buffer, 128KiBstatic intTINY_ALLOCATION_LIMITstatic intTINY_ALLOCATION_UNITstatic intTINY_CHUNK_SIZE
-
Constructor Summary
Constructors Constructor Description BufferPool(java.lang.String name, long memoryUsageThreshold, boolean recyclePartially)
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description BufferPool.LocalPoolcreate()voiddebug(org.apache.cassandra.utils.memory.BufferPool.Debug newDebug, BufferPool.DebugLeaks newDebugLeaks)java.nio.ByteBufferget(int size, BufferType bufferType)java.nio.ByteBuffergetAtLeast(int size, BufferType bufferType)org.apache.cassandra.utils.memory.BufferPool.GlobalPoolglobalPool()longmemoryUsageThreshold()BufferPoolMetricsmetrics()longoverflowMemoryInBytes()voidput(java.nio.ByteBuffer buffer)voidputUnusedPortion(java.nio.ByteBuffer buffer)voidreleaseLocal()Forces 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, java.util.concurrent.TimeUnit unit)longsizeInBytes()java.nio.ByteBuffertryGet(int size)Unlike the get methods, this will return null if the pool is exhaustedjava.nio.ByteBuffertryGetAtLeast(int size)voidunsafeReset()This is not thread safe and should only be used for unit testing.java.nio.ByteBufferunwrapBufferPoolManagedBuffer(java.nio.ByteBuffer originalBuffer)longusedSizeInBytes()
-
-
-
Field Detail
-
NORMAL_CHUNK_SIZE
public static final int NORMAL_CHUNK_SIZE
The size of a page aligned buffer, 128KiB- See Also:
- Constant Field Values
-
NORMAL_ALLOCATION_UNIT
public static final int NORMAL_ALLOCATION_UNIT
- See Also:
- Constant Field Values
-
TINY_CHUNK_SIZE
public static final int TINY_CHUNK_SIZE
- See Also:
- Constant Field Values
-
TINY_ALLOCATION_UNIT
public static final int TINY_ALLOCATION_UNIT
- See Also:
- Constant Field Values
-
TINY_ALLOCATION_LIMIT
public static final int TINY_ALLOCATION_LIMIT
- See Also:
- Constant Field Values
-
name
protected final java.lang.String name
-
metrics
protected final BufferPoolMetrics metrics
-
-
Method Detail
-
create
public BufferPool.LocalPool create()
- Returns:
- a local pool instance and caller is responsible to release the pool
-
get
public java.nio.ByteBuffer get(int size, BufferType bufferType)
-
getAtLeast
public java.nio.ByteBuffer getAtLeast(int size, BufferType bufferType)
-
tryGet
public java.nio.ByteBuffer tryGet(int size)
Unlike the get methods, this will return null if the pool is exhausted
-
tryGetAtLeast
public java.nio.ByteBuffer tryGetAtLeast(int size)
-
put
public void put(java.nio.ByteBuffer buffer)
-
putUnusedPortion
public void putUnusedPortion(java.nio.ByteBuffer buffer)
-
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, java.util.concurrent.TimeUnit unit) throws java.lang.InterruptedException, java.util.concurrent.TimeoutException- Throws:
java.lang.InterruptedExceptionjava.util.concurrent.TimeoutException
-
metrics
public BufferPoolMetrics metrics()
-
unsafeReset
public void unsafeReset()
This is not thread safe and should only be used for unit testing.
-
unwrapBufferPoolManagedBuffer
public java.nio.ByteBuffer unwrapBufferPoolManagedBuffer(java.nio.ByteBuffer originalBuffer)
- Returns:
- the inner buffer if it has a BufferPool.Chunk attached and originalBuffer in other cases
-
-