public static ByteBuffer allocateForDirectIO(DirectIOLib lib, int capacity) {
        if (capacity % lib.blockSize() > 0) {
            throw new IllegalArgumentException("Capacity (" + capacity + ") must be a multiple"
                + "of the block size (" + lib.blockSize() + ")");
        }
        NativeLong blockSize = new NativeLong(lib.blockSize());
        PointerByReference pointerToPointer = new PointerByReference();

        // align memory for use with O_DIRECT
        DirectIOLib.posix_memalign(pointerToPointer, blockSize, new NativeLong(capacity));
        return wrapPointer(Pointer.nativeValue(pointerToPointer.getValue()), capacity);
    }
Allocate <tt>capacity</tt> bytes of native memory for use as a buffer, and
return a {@link ByteBuffer} which gives an interface to this memory. The
memory is allocated with
{@link DirectIOLib#posix_memalign(PointerByReference, NativeLong, NativeLong) DirectIOLib#posix_memalign()}
to ensure that the buffer can be used with <tt>O_DIRECT</tt>.
*

@param capacity The requested number of bytes to allocate
@return A new JnaMemAlignedBuffer of <tt>capacity</tt> bytes aligned in native memory.
s3stream/src/main/java/com/automq/stream/thirdparty/moe/cnkirito/kdio/DirectIOUtils.java