javareal-timelow-latencychroniclechronicle-queue

What is the correct way of doing Java IPC through /dev/shm (with the lowest possible latency)


I'm trying to code an IPC solution through /dev/shm.

@SK-logic gave me some pointers in the comments here: Chronicle: How to optimize memory-mapped files for low-latency?

My doubt is: Should I use a MappedByteBuffer or just a plain FileChannel?

With a MappedByteBuffer I can use sun.misc.Unsafe and have direct access to memory. That's fantastic because Unsafe gives me methods like getLongVolatile (in addition to getLong) and putLongVolatile (in addition to putLong). Is that even possible if I use a plain FileChannel? How would I avoid reading cached data from the CPU cache with a plain FileChannel reading from /dev/shm/? Do I have to configure something in the operating system for volatile reads and writes from /dev/shm? What? Where? How? :)

What is the correct way of doing Java IPC through /dev/shm? Plain FileChannel? MappedByteBuffer?

Below how I get the pointer to memory through sun.misc.Unsafe:

    try {
        this.raf = new RandomAccessFile(file, "rw");
        this.fileChannel = raf.getChannel();
        this.mappedBuffer = this.fileChannel.map(MapMode.READ_WRITE, 0, size);
    } catch (Exception e) {
        throw new RuntimeException("Could not mmap file to memory: " + filename + " " + size, e);
    }
    
    try {
        addressField = Buffer.class.getDeclaredField("address");
        addressField.setAccessible(true);
        this.pointer = (long) addressField.get(this.mappedBuffer);
    } catch(Exception e) {
        throw new RuntimeException("Could not get off-heap pointer!", e);
    }

Solution

  • Chronicle Queue uses Unsafe for thread-safe memory access for heap and direct memory.

    While this works, the JVM doesn't provide any guarantees as to how your system will behave. We test on Intel X64, AMD, and ARM processors.

    Rather than writing this all yourself, why not try Chronicle Map or Queue to do this for you?