JNI直接缓冲区。谁负责本地缓冲区释放?
假设一方面我们有一个用env->NewDirectByteBuffer()
创建的直接字节缓冲区。另一方面,我们有类似的直接缓冲区,但是用ByteBuffer.allocateDirect()
创建。显然,这两个对象都应该由JVM以相同的方式进行管理,包括管理支持本地缓冲区,第一种情况由用户提供,第二种情况由JVM从本地堆中分配。JNI直接缓冲区。谁负责本地缓冲区释放?
当然JVM必须在第二个对象的GC_ing过程中释放后台缓冲区(用ByteBuffer.allocateDirect()
实例化)。
我的问题:JVM会在第一个对象的GC_ing期间尝试释放缓冲区(用env->NewDirectByteBuffer()
实例化)?
P.S.在JNI文档中,我都没有找到明确的答案。最有用的信息在这里http://www.ibm.com/developerworks/library/j-nativememory-linux/index.html:
直接ByteBuffer对象会自动清理自己的本地缓存 但只能做这么为Java堆GC的一部分 - 所以他们不 自动应对压力本机堆。
所以看起来JVM会在GC传递过程中释放后台缓冲区,但是没有任何关于释放器的提及。是平原free()
还是别的什么。
当你调用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。
如果您通过ByteBuffer.allocateDirect()
创建DirectByteBuffer
,则会设置cleaner
属性(请参阅源代码DirectByteBuffer
)。
现在清洁器是一个实用程序对象,其clean
方法当缓冲器是垃圾收集运行(参见本explanation细节)。
对于通过ByteBuffer.allocateDirect()
构建的缓冲区,清理程序将释放直接内存。
对于JNI构造的缓冲区,没有这样的操作完成。你需要自己释放这个记忆。
清除。看起来像Android使用相同的方法。 Android SDK详尽评论:'/ ** *表示我们不拥有的一块内存。 (我们没有取得对应于 *的内存的所有权来指导由JNI NewDirectByteBuffer函数创建的缓冲区。) * /' – Sergio