如何以可移植的方式分配堆外字节缓冲区?

How to allocate an off-heap byte buffer in a portable way?

有没有办法分配一个简单的堆外字节缓冲区同时针对 jdk-8 和 jdk-11(即不可能使用 UnsafeVarHandle?

当前解决方案依赖于RandomAccessFile,但目标是仅使用直接内存。

我正在尝试 ByteBuffer.allocateDirect(),但看起来它仍然受到堆大小的限制。

 * $JDK_16/bin/jshell -R-Xmx32m 
jshell> java.nio.ByteBuffer.allocateDirect(33 * 1024 * 1024)
|  Exception java.lang.OutOfMemoryError: Cannot reserve 34603008 bytes of direct buffer memory (allocated: 141, limit: 33554432)
|        at Bits.reserveMemory (Bits.java:178)
|        at DirectByteBuffer.<init> (DirectByteBuffer.java:121)
|        at ByteBuffer.allocateDirect (ByteBuffer.java:330)
|        at (#1:1)

How to allocate an off-heap byte buffer in a portable way?

使用ByteBuffer.allocateDirect(capacity);有关详细信息,请参阅 javadoc。 (另请阅读顶部解释普通缓冲区和直接缓冲区之间差异的部分,并列出使用直接缓冲区的一些注意事项。)

I'm trying ByteBuffer.allocateDirect(), but it looks like it's still limited by the heap size.

不受堆大小限制(-Xmx)。它实际上受限于:

  • 显式 -XX:MaxDirectMemorySize=size 选项或默认 MaxDirectMemorySize 值,并且
  • 操作系统准备在 JVM 请求时分配多少内存。

java 手册页对上述选项的说明如下:

"By default, the size is set to 0, meaning that the JVM chooses the size for NIO direct-buffer allocations automatically."

如何做出选择可能是 Java 版本和 OS 特定的,并且可能会考虑您的硬件(或虚拟机)平台的尺寸。