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

时间:2016-02-12 13:11:20

标签: java c java-native-interface

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

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

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

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

  

Direct ByteBuffer对象自动清理其本机缓冲区   但只能作为Java堆GC的一部分这样做 - 所以他们不这样做   自动响应本机堆上的压力。

因此看起来JVM会在GC传递期间释放后备缓冲区,但是没有任何关于deallocator的提及。是free()还是别的。

1 个答案:

答案 0 :(得分:3)

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

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

请注意cleaner属性为null。

如果您通过DirectByteBuffer创建ByteBuffer.allocateDirect(),则会设置cleaner属性(请参阅DirectByteBuffer的源代码)。

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

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

对于JNI构造的缓冲区,不执行此类操作。你需要自己释放这个记忆。