Class ByteBuffAllocator
- Direct Known Subclasses:
DeallocateRewriteByteBuffAllocator
ByteBuff
s which are wrappers of
offheap ByteBuffer
usually. If we are sure that the returned ByteBuffs have reached the
end of their life cycle, we must call ByteBuff.release()
to return buffers to the pool
otherwise the pool will leak. If the desired memory size is larger than what the ByteBufferPool
has available, we'll downgrade to allocate ByteBuffers from the heap. Increase the ByteBufferPool
size if detect this case.For better memory/pool utilization, there is a lower bound named
minSizeForReservoirUse
in this allocator, and if the desired size is less than
minSizeForReservoirUse
, the allocator will just allocate the ByteBuffer from heap
and let the JVM manage memory, because it better to not waste pool slots allocating a single
fixed-size ByteBuffer for a small object.This pool can be used anywhere it makes sense managing memory. Currently used at least by RPC.
-
Nested Class Summary
-
Field Summary
Modifier and TypeFieldDescriptionstatic final String
static final String
private final Queue<ByteBuffer>
protected final int
static final String
Set an alternate bytebuffallocator by setting this config, e.g.static final int
There're some reasons why better to choose 65KB(rather than 64KB) as the default buffer size:static final String
Deprecated.since 2.3.0 and will be removed in 4.0.0.(package private) static final String
Deprecated.since 2.3.0 and will be removed in 4.0.0.(package private) static final String
Deprecated.since 2.3.0 and will be removed in 4.0.0.static final ByteBuffAllocator
private final LongAdder
private long
private long
private static final org.slf4j.Logger
static final String
private final int
private boolean
static final String
private final int
static final ByteBuffAllocator.Recycler
private final LongAdder
protected final boolean
private final AtomicInteger
-
Constructor Summary
ModifierConstructorDescriptionprotected
ByteBuffAllocator
(boolean reservoirEnabled, int maxBufCount, int bufSize, int minSizeForReservoirUse) -
Method Summary
Modifier and TypeMethodDescriptionallocate
(int size) Allocate size bytes from the ByteBufAllocator, Note to call theByteBuff.release()
if no need any more, otherwise the memory leak happen in NIO ByteBuffer pool.Allocate an buffer with buffer size from ByteBuffAllocator, Note to call theByteBuff.release()
if no need any more, otherwise the memory leak happen in NIO ByteBuffer pool.private ByteBuffer
allocateOnHeap
(int size) void
clean()
Free all direct buffers if allocated, mainly used for testing.static ByteBuffAllocator
create
(org.apache.hadoop.conf.Configuration conf, boolean reservoirEnabled) Initialize anByteBuffAllocator
which will try to allocate ByteBuffers from off-heap if reservoir is enabled and the reservoir has enough buffers, otherwise the allocator will just allocate the insufficient buffers from on-heap to meet the requirement.private static ByteBuffAllocator
Initialize anByteBuffAllocator
which only allocate ByteBuffer from on-heap, it's designed for testing purpose or disabled reservoir case.private ByteBuffer
int
int
TheConcurrentLinkedQueue.size()
is O(N) complexity and time-consuming, so DO NOT use the method except in UT.long
static long
getHeapAllocationBytes
(ByteBuffAllocator... allocators) static double
getHeapAllocationRatio
(ByteBuffAllocator... allocators) long
int
int
boolean
protected void
putbackBuffer
(ByteBuffer buf) Return back a ByteBuffer after its use.
-
Field Details
-
LOG
-
HEAP
-
ALLOCATOR_POOL_ENABLED_KEY
- See Also:
-
MAX_BUFFER_COUNT_KEY
- See Also:
-
BUFFER_SIZE_KEY
- See Also:
-
MIN_ALLOCATE_SIZE_KEY
- See Also:
-
BYTEBUFF_ALLOCATOR_CLASS
Set an alternate bytebuffallocator by setting this config, e.g. we can configDeallocateRewriteByteBuffAllocator
to find out prematurely release issues- See Also:
-
DEPRECATED_ALLOCATOR_POOL_ENABLED_KEY
Deprecated.since 2.3.0 and will be removed in 4.0.0. UseALLOCATOR_POOL_ENABLED_KEY
instead.- See Also:
-
DEPRECATED_MAX_BUFFER_COUNT_KEY
Deprecated.since 2.3.0 and will be removed in 4.0.0. UseMAX_BUFFER_COUNT_KEY
instead.- See Also:
-
DEPRECATED_BUFFER_SIZE_KEY
Deprecated.since 2.3.0 and will be removed in 4.0.0. UseBUFFER_SIZE_KEY
instead.- See Also:
-
DEFAULT_BUFFER_SIZE
There're some reasons why better to choose 65KB(rather than 64KB) as the default buffer size:1. Almost all of the data blocks have the block size: 64KB + delta, whose delta is very small, depends on the size of lastKeyValue. If we set buffer.size=64KB, then each block will be allocated as a MultiByteBuff: one 64KB DirectByteBuffer and delta bytes HeapByteBuffer, the HeapByteBuffer will increase the GC pressure. Ideally, we should let the data block to be allocated as a SingleByteBuff, it has simpler data structure, faster access speed, less heap usage.
2. Since the blocks are MultiByteBuff when using buffer.size=64KB, so we have to calculate the checksum by an temp heap copying (see HBASE-21917), while if it's a SingleByteBuff, we can speed the checksum by calling the hadoop' checksum in native lib, which is more faster.
For performance comparison, please see HBASE-22483.
- See Also:
-
NONE
-
reservoirEnabled
-
bufSize
-
maxBufCount
-
usedBufCount
-
maxPoolSizeInfoLevelLogged
-
minSizeForReservoirUse
-
buffers
-
poolAllocationBytes
-
heapAllocationBytes
-
lastPoolAllocationBytes
-
lastHeapAllocationBytes
-
-
Constructor Details
-
ByteBuffAllocator
protected ByteBuffAllocator(boolean reservoirEnabled, int maxBufCount, int bufSize, int minSizeForReservoirUse)
-
-
Method Details
-
create
public static ByteBuffAllocator create(org.apache.hadoop.conf.Configuration conf, boolean reservoirEnabled) Initialize anByteBuffAllocator
which will try to allocate ByteBuffers from off-heap if reservoir is enabled and the reservoir has enough buffers, otherwise the allocator will just allocate the insufficient buffers from on-heap to meet the requirement.- Parameters:
conf
- which get the arguments to initialize the allocator.reservoirEnabled
- indicate whether the reservoir is enabled or disabled. NOTICE: if reservoir is enabled, then we will use the pool allocator to allocate off-heap ByteBuffers and use the HEAP allocator to allocate heap ByteBuffers. Otherwise if reservoir is disabled then all allocations will happen in HEAP instance.- Returns:
- ByteBuffAllocator to manage the byte buffers.
-
createOnHeap
Initialize anByteBuffAllocator
which only allocate ByteBuffer from on-heap, it's designed for testing purpose or disabled reservoir case.- Returns:
- allocator to allocate on-heap ByteBuffer.
-
isReservoirEnabled
-
getHeapAllocationBytes
-
getPoolAllocationBytes
-
getBufferSize
-
getUsedBufferCount
-
getFreeBufferCount
TheConcurrentLinkedQueue.size()
is O(N) complexity and time-consuming, so DO NOT use the method except in UT. -
getTotalBufferCount
-
getHeapAllocationBytes
-
getHeapAllocationRatio
-
allocateOneBuffer
Allocate an buffer with buffer size from ByteBuffAllocator, Note to call theByteBuff.release()
if no need any more, otherwise the memory leak happen in NIO ByteBuffer pool.- Returns:
- an ByteBuff with the buffer size.
-
allocateOnHeap
-
allocate
Allocate size bytes from the ByteBufAllocator, Note to call theByteBuff.release()
if no need any more, otherwise the memory leak happen in NIO ByteBuffer pool.- Parameters:
size
- to allocate- Returns:
- an ByteBuff with the desired size.
-
clean
Free all direct buffers if allocated, mainly used for testing. -
getBuffer
- Returns:
- One free DirectByteBuffer from the pool. If no free ByteBuffer and we have not reached the maximum pool size, it will create a new one and return. In case of max pool size also reached, will return null. When pool returned a ByteBuffer, make sure to return it back to pool after use.
-
putbackBuffer
Return back a ByteBuffer after its use. Don't read/write the ByteBuffer after the returning.- Parameters:
buf
- ByteBuffer to return.
-