Class BufferPool
- java.lang.Object
-
- org.apache.cassandra.utils.memory.BufferPool
-
public class BufferPool extends java.lang.Object
A pool of ByteBuffers that can be recycled to reduce system direct memory fragmentation and improve buffer allocation performance. EachBufferPool
instance has oneBufferPool.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.LocalPool
to 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 byChunkCache
. 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 │ ↑ │ └────────────────────────────────────────────────────────────────────────────────┘
- Macro Chunk
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static interface
BufferPool.DebugLeaks
class
BufferPool.LocalPool
A thread local class that grabs chunks from the global pool for this thread allocations.
-
Field Summary
Fields Modifier and Type Field Description protected BufferPoolMetrics
metrics
protected java.lang.String
name
static int
NORMAL_ALLOCATION_UNIT
static int
NORMAL_CHUNK_SIZE
The size of a page aligned buffer, 128KiBstatic int
TINY_ALLOCATION_LIMIT
static int
TINY_ALLOCATION_UNIT
static int
TINY_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.LocalPool
create()
void
debug(org.apache.cassandra.utils.memory.BufferPool.Debug newDebug, BufferPool.DebugLeaks newDebugLeaks)
java.nio.ByteBuffer
get(int size, BufferType bufferType)
java.nio.ByteBuffer
getAtLeast(int size, BufferType bufferType)
org.apache.cassandra.utils.memory.BufferPool.GlobalPool
globalPool()
long
memoryUsageThreshold()
BufferPoolMetrics
metrics()
long
overflowMemoryInBytes()
void
put(java.nio.ByteBuffer buffer)
void
putUnusedPortion(java.nio.ByteBuffer buffer)
void
releaseLocal()
Forces to recycle free local chunks back to the global pool.static int
roundUp(int size)
static int
roundUp(int size, int unit)
void
setRecycleWhenFreeForCurrentThread(boolean recycleWhenFree)
void
shutdownLocalCleaner(long timeout, java.util.concurrent.TimeUnit unit)
long
sizeInBytes()
java.nio.ByteBuffer
tryGet(int size)
Unlike the get methods, this will return null if the pool is exhaustedjava.nio.ByteBuffer
tryGetAtLeast(int size)
void
unsafeReset()
This is not thread safe and should only be used for unit testing.long
usedSizeInBytes()
-
-
-
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.InterruptedException
java.util.concurrent.TimeoutException
-
metrics
public BufferPoolMetrics metrics()
-
unsafeReset
public void unsafeReset()
This is not thread safe and should only be used for unit testing.
-
-