0

我正在阅读 HBase 文档并遇到了堆外读取路径 据我了解,堆外是内存中 Java 存储垃圾收集器范围之外的字节/对象的地方。我还去搜索了一些有助于使用堆外内存的库并找到了 Ehcatche但是,我找不到任何来自 oracle 或 JVM 的关于他的官方文档。那么这是 JVM 的标准功能还是某种 hack,如果它是用于执行此操作的底层类和技术是什么?

4

1 回答 1

2

你应该寻找ByteBuffer

直接与非直接缓冲区

字节缓冲区可以是直接的,也可以是非直接的。给定一个直接字节缓冲区,Java 虚拟机将尽最大努力直接在其上执行本机 I/O 操作。也就是说,它将尝试避免在每次调用底层操作系统的本机 I/O 操作之一之前(或之后)将缓冲区的内容复制到(或从)中间缓冲区。

可以通过调用此类的 allocateDirect 工厂方法来创建直接字节缓冲区。此方法返回的缓冲区通常比非直接缓冲区具有更高的分配和释放成本。直接缓冲区的内容可能驻留在正常的垃圾收集堆之外,因此它们对应用程序内存占用的影响可能并不明显。因此,建议将直接缓冲区主要分配给受底层系统的本机 I/O 操作影响的大型、长期存在的缓冲区。通常,最好仅在直接缓冲区对程序性能产生可测量的增益时才分配它们。

也可以通过将文件的区域直接映射到内存来创建直接字节缓冲区。Java 平台的实现可以选择支持通过 JNI 从本机代码创建直接字节缓冲区。如果其中一种缓冲区的实例引用了不可访问的内存区域,则访问该区域的尝试不会更改缓冲区的内容,并且会在访问时或稍后引发未指定的异常时间。

字节缓冲区是直接的还是非直接的可以通过调用它的 isDirect 方法来确定。提供此方法以便可以在性能关键代码中完成显式缓冲区管理。

如何处理直接 ByteBuffers 取决于 JVM 实现,但至少 OpenJDK JVM 是在堆外分配内存。

JEP 383 : Foreign-Memory Access API (Second Incubator)功能正在Java 15中孵化。此功能将通过提供公共 API 使访问堆外内存成为标准。

于 2021-03-09T14:41:30.853 回答