private void release(final ByteBuffer buffer) {
        // This method is called a LOT so needs to be performant
        if (buffer != null && buffer.isDirect()) {
            // Not certain we need to zero the buffer if clear is called as any users of it
            // should be immediately writing to part of it and setting the limit/pos
//            for (int i = buffer.position(); i < buffer.limit(); i++) {
//                buffer.put((byte)0);
//            }
            buffer.clear();

            try {
                int count = 0;
                int capacity = buffer.capacity();

                while (true) {
                    count++;
                    final Key key = new Key(capacity, System.nanoTime());
                    final ByteBuffer prevValue = bufferMap.putIfAbsent(key, buffer);
                    if (prevValue == null) {
                        // No existing mapping
                        break;
                    }
                    // Buffers are indexed by (capacity, time) to ensure unique keys.
                    // If our key is not unique on the first try, we try again, since the
                    // time will be different.  Since we use nanoseconds, it's pretty
                    // unlikely that we'll loop even once, unless the system clock has a
                    // poor granularity.
                }
                if (count > 1) {
                    LOGGER.warn("Took {} iterations to put buffer", count);
                }
            } catch (Exception e) {
                // if a buffer is not released back to the pool then it is not the end of the world
                // is we can just create more as required.
                throw new RuntimeException("Error releasing buffer back to the pool", e);
            }
        }
//        if (LOGGER.isDebugEnabled()) {
//            releaseCount.incrementAndGet();
//        }
    }
An unbounded self-populating pool of directly allocated ByteBuffers.
When using one of the methods to get/use a buffer from the pool the
smallest available buffer that is greater than or equal to the required
capacity will be provided. All buffers will be cleared on return to
the pool.
<p>
As this pool is un-bounded it could grow very large under high contention.
<p>
This impl uses a {@link ConcurrentSkipListMap} keyed on capacity and insert time
with no synchronisation.
stroom-bytebuffer/src/main/java/stroom/bytebuffer/ByteBufferPoolImpl.java