Class ByteBuffAllocator
- Direct Known Subclasses:
DeallocateRewriteByteBuffAllocator
ByteBuffs 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
Nested Classes -
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final Stringstatic final Stringprivate final Queue<ByteBuffer>protected final intstatic final StringSet an alternate bytebuffallocator by setting this config, e.g.static final intThere're some reasons why better to choose 65KB(rather than 64KB) as the default buffer size:static final StringDeprecated.since 2.3.0 and will be removed in 4.0.0.(package private) static final StringDeprecated.since 2.3.0 and will be removed in 4.0.0.(package private) static final StringDeprecated.since 2.3.0 and will be removed in 4.0.0.static final ByteBuffAllocatorprivate final LongAdderprivate longprivate longprivate static final org.slf4j.Loggerstatic final Stringprivate final intprivate booleanstatic final Stringprivate final intstatic final ByteBuffAllocator.Recyclerprivate final LongAdderprotected final booleanprivate final AtomicInteger -
Constructor Summary
ConstructorsModifierConstructorDescriptionprotectedByteBuffAllocator(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 ByteBufferallocateOnHeap(int size) voidclean()Free all direct buffers if allocated, mainly used for testing.static ByteBuffAllocatorcreate(org.apache.hadoop.conf.Configuration conf, boolean reservoirEnabled) Initialize anByteBuffAllocatorwhich 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 ByteBuffAllocatorInitialize anByteBuffAllocatorwhich only allocate ByteBuffer from on-heap, it's designed for testing purpose or disabled reservoir case.private ByteBufferintintTheConcurrentLinkedQueue.size()is O(N) complexity and time-consuming, so DO NOT use the method except in UT.longstatic longgetHeapAllocationBytes(ByteBuffAllocator... allocators) static doublegetHeapAllocationRatio(ByteBuffAllocator... allocators) longintintbooleanprotected voidputbackBuffer(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 configDeallocateRewriteByteBuffAllocatorto 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_KEYinstead.- See Also:
-
DEPRECATED_MAX_BUFFER_COUNT_KEY
Deprecated.since 2.3.0 and will be removed in 4.0.0. UseMAX_BUFFER_COUNT_KEYinstead.- See Also:
-
DEPRECATED_BUFFER_SIZE_KEY
Deprecated.since 2.3.0 and will be removed in 4.0.0. UseBUFFER_SIZE_KEYinstead.- 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 anByteBuffAllocatorwhich 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 anByteBuffAllocatorwhich 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.
-