通过 /dev/shm 执行 Java IPC 的正确方法是什么(尽可能低的延迟)
What is the correct way of doing Java IPC through /dev/shm (with the lowest possible latency)
我正在尝试通过 /dev/shm
编写 IPC 解决方案。
@SK-logic 在评论中给了我一些建议:
我的疑问是: 我应该使用 MappedByteBuffer
还是简单的 FileChannel
?
使用 MappedByteBuffer
我可以使用 sun.misc.Unsafe
并可以直接访问内存。这太棒了,因为 Unsafe
给了我像 getLongVolatile
(除了 getLong
)和 putLongVolatile
(除了 putLong
)这样的方法。如果我使用普通的 FileChannel
,这甚至可能吗?我如何避免从 CPU 缓存中读取缓存数据,而从 /dev/shm/
中读取 FileChannel
?我是否必须在操作系统中配置某些内容才能从 /dev/shm
进行易失性读取和写入?什么?在哪里?如何? :)
通过 /dev/shm
执行 Java IPC 的正确方法是什么?普通文件通道? MappedByteBuffer?
下面是我如何通过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);
}
Chronicle Queue 使用 Unsafe
进行堆和直接内存的 thread-safe 内存访问。
虽然这有效,但 JVM 不对您的系统的行为方式提供任何保证。我们在 Intel X64、AMD 和 ARM 处理器上进行测试。
与其自己编写所有这些,不如尝试使用 Chronicle Map 或 Queue 来为您完成这些工作?
我正在尝试通过 /dev/shm
编写 IPC 解决方案。
@SK-logic 在评论中给了我一些建议:
我的疑问是: 我应该使用 MappedByteBuffer
还是简单的 FileChannel
?
使用 MappedByteBuffer
我可以使用 sun.misc.Unsafe
并可以直接访问内存。这太棒了,因为 Unsafe
给了我像 getLongVolatile
(除了 getLong
)和 putLongVolatile
(除了 putLong
)这样的方法。如果我使用普通的 FileChannel
,这甚至可能吗?我如何避免从 CPU 缓存中读取缓存数据,而从 /dev/shm/
中读取 FileChannel
?我是否必须在操作系统中配置某些内容才能从 /dev/shm
进行易失性读取和写入?什么?在哪里?如何? :)
通过 /dev/shm
执行 Java IPC 的正确方法是什么?普通文件通道? MappedByteBuffer?
下面是我如何通过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);
}
Chronicle Queue 使用 Unsafe
进行堆和直接内存的 thread-safe 内存访问。
虽然这有效,但 JVM 不对您的系统的行为方式提供任何保证。我们在 Intel X64、AMD 和 ARM 处理器上进行测试。
与其自己编写所有这些,不如尝试使用 Chronicle Map 或 Queue 来为您完成这些工作?