Fast erase (not clear) a ByteBuffer in Java

Have you tried using one of the ByteBuffer.put(byte[]) or ByteBuffer.put(ByteBuffer) methods to write multiple zeros in one go? You could then iterate over the buffer in chunks of 100 or 1000 bytes, or whatever, using an array or buffer pre-filled with zeros.

Downside: this is an optional operation, so not all implementations of ByteBuffer are required to provide it...


If you need a fresh clean zero-filled ByteBuffer after the hash table is flushed, the easiest way is to drop the existing ByteBuffer and allocate a new one. The official documentation does not say so, but all known implementations zero the memory of new buffers. See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6535542 for additional info.


As DNA mentions, having a pre-filled buffer and using ByteBuffer.put(ByteBuffer) is probably the fastest portable way. If that's not practical, you can do something like this to take advantage of either Arrays.fill or Unsafe.putLong when applicable:

public static void fill(ByteBuffer buf, byte b) {
    if (buf.hasArray()) {
        final int offset = buf.arrayOffset();
        Arrays.fill(buf.array(), offset + buf.position(), offset + buf.limit(), b);
        buf.position(buf.limit());
    } else {
        int remaining = buf.remaining();
        if (UNALIGNED_ACCESS) {
            final int i = (b << 24) | (b << 16) | (b << 8) | b;
            final long l = ((long) i << 32) | i;
            while (remaining >= 8) {
                buf.putLong(l);
                remaining -= 8;
            }
        }
        while (remaining-- > 0) {
            buf.put(b);
        }
    }
}

Setting UNALIGNED_ACCESS requires some knowledge of your JRE implementation and platform. Here's how I would set it for the Oracle JRE when also using JNA (which provides Platform.ARCH as a convenient, canonical way to access the os.arch system property).

/**
 * Indicates whether the ByteBuffer implementation likely supports unaligned
 * access of multi-byte values on the current platform.
 */
private static final boolean UNALIGNED_ACCESS = Platform.ARCH.startsWith("x86");

For ByteBuffer implementations that provide the optional array() method (where hasArray() returns true), you could use this method get a reference to the underlying array, then use java.util.Arrays#fill().