【问题标题】:How to allocate an off-heap byte buffer in a portable way?如何以可移植的方式分配堆外字节缓冲区?
【发布时间】:2021-12-28 22:52:49
【问题描述】:

有没有办法在同时针对 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)

【问题讨论】:

  • 你想做什么需要堆外字节缓冲区?请edit您的问题包含对您正在尝试做的事情的更详细描述。这个问题看起来像XY problem
  • ByteBuffer,从 (java) 1.4 开始
  • ByteBuffer.allocateDirect(capacity)
  • @Stephen 但是 ByteBuffer 不受堆大小 (Xmx) 的限制吗?
  • 使用 MappedByteBuffer docs.oracle.com/javase/7/docs/api/java/nio/… 你必须创建一个 FileChannel 并从那里映射来获取一个实例

标签: java java-8


【解决方案1】:

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

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

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

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

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

java 手册页说明了上述选项:

“默认情况下,大小设置为 0,这意味着 JVM 会自动选择 NIO 直接缓冲区分配的大小。”

如何做出选择取决于 Java 版本和操作系统,并且可能会考虑到您的硬件(或虚拟机)平台的尺寸。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-10
    • 1970-01-01
    • 1970-01-01
    • 2012-12-13
    • 1970-01-01
    • 1970-01-01
    • 2021-12-29
    相关资源
    最近更新 更多