ByteBuffer (int size) { if (useBuffersCache()) { Map.Entry<Integer, ArrayBlockingQueue<ByteBuffer>> buffersOfCapacity = buffersPool.ceilingEntry(size); while (buffersOfCapacity != null) { int capacity = buffersOfCapacity.getKey(); if (capacity > size * 2) { //It's ok to use buffer(capacity: 32k) to serve request of size=16k, but we don't want to // use 10M buffer to serve request of size=16k because it is too much waste. // By limiting the capacity <=2*size we limit the amount of memory wasted due to 'rounding'. // If we can't serve the request from pool wasting no more than twice the requested memory // -- fallback to allocating the buffer from JVM (and hope JVM/stdlib/OS allocators are // smart enough to not waste even more memory than we could have been wasted :). break; } ByteBuffer cachedBuffer = buffersOfCapacity.getValue().poll(); if (cachedBuffer != null) { cachedBuffer.clear().limit(size); totalSizeOfBuffersInCache.addAndGet(-capacity); hits.incrementAndGet(); return cachedBuffer; } //Don't remove the entry even though it is empty -- because it creates race condition // with adding the same entry again, and some buffers may be lost due to that race. buffersOfCapacity = buffersPool.higherEntry(capacity); } } misses.incrementAndGet(); totalSizeOfBuffersAllocated.addAndGet(size); return allocateNewBuffer(size); }