JNI直接缓冲.谁负责本机缓冲区释放?

Ser*_*gio 6 c java java-native-interface

假设一方面我们有一个直接字节缓冲区env->NewDirectByteBuffer().另一方面,我们有类似的直接缓冲区,但创建了ByteBuffer.allocateDirect().显然,这两个对象应该由JVM以相同的方式管理,包括后端本机缓冲区的管理,第一种情况是由用户提供,第二种情况是由JVM从本机堆分配的.

当然,JVM必须在第二个对象(实例化ByteBuffer.allocateDirect())的GC期间释放后备缓冲区.

我的问题是:JVM是否会在第一个对象(实例化env->NewDirectByteBuffer())的GC期间尝试释放缓冲区?

PS我也没有在JNI医生处找到明确的答案.最有用的信息是http://www.ibm.com/developerworks/library/j-nativememory-linux/index.html:

Direct ByteBuffer对象自动清理其本机缓冲区,但只能作为Java堆GC的一部分执行 - 因此它们不会自动响应本机堆上的压力.

所以看起来JVM会在GC传递过程中释放后备缓冲区,但是没有任何关于deallocator的提及.是明白free()还是别的什么.

wer*_*ero 8

当您调用 JNI 时,将使用以下构造函数创建NewDirectByteBuffer(void* address, jlong capacity)一个DirectByteBuffer对象:

private DirectByteBuffer(long addr, int cap) {
    super(-1, 0, cap, cap);
    address = addr;
    cleaner = null;
    att = null;
}
Run Code Online (Sandbox Code Playgroud)

请注意,该cleaner属性为空。

如果您创建一个DirectByteBuffer通过ByteBuffer.allocateDirect()cleaner属性设置(见的源代码DirectByteBuffer)。

现在清洁器是一个实用程序对象,它的clean方法在缓冲区被垃圾收集时运行(有关详细信息,请参阅此说明)。

对于通过ByteBuffer.allocateDirect()清洁器构造的缓冲区,释放直接内存。

对于 JNI 构造的缓冲区,不进行此类操作。您需要自己释放此内存。