何时以及如何释放NIO直接缓冲区?

5

我有一个C库需要一个临时缓冲区用于临时存储。我正在考虑将直接字节缓冲区的地址传递给它。

  • 在最终释放之前,VM是否允许重定位缓冲区?本地库将在JNI帧消失后保持指针。我的理解是JNI本地对象引用不能被缓存,因为VM可能在GC期间重新定位它们。这是否适用于缓冲区地址?

  • 我知道如果我在Java中分配缓冲区然后让缓冲区对象超出范围,VM会释放缓冲区内存。如果我在本地代码中使用NewDirectByteBuffer创建一个新的缓冲区,谁负责释放支持内存?

  • 如果我在本地代码中使用NewDirectByteBuffer创建一个新的缓冲区并使用已经被直接缓冲区使用的地址,会发生什么?内存会被双倍释放吗?当最后一个引用该内存块的缓冲区被垃圾回收时,VM会引用计数内存块并尝试释放它吗?

1个回答

6

直接缓冲区在最终释放之前,VM是否允许重定位缓冲区?

不会重定位,因为直接缓冲区不是GC堆的一部分。

如果我在本地代码中使用NewDirectByteBuffer创建一个新的缓冲区,是谁负责释放支持内存?

它由您(本地代码)负责释放。JVM无法知道用于分配该支持存储器的方法(可能是malloc,可能是静态缓冲区等)。

如果我使用NewDirectByteBuffer在本地代码中创建一个新的缓冲区,并使用已被直接缓冲区使用的地址,会发生什么?

鉴于VM不会尝试释放传递给NewDirectByteBuffer的内存地址,如果两次传递相同的地址,则不会发生任何事情。


1
我找不到任何官方的Java文档说明本地代码负责释放缓冲区。 - Raedwald
@Raedwald 我建议你阅读这篇文章:http://www.ibm.com/developerworks/library/j-nativememory-linux/index.html。管理 Java 堆由垃圾收集器负责,而管理本地堆则由你自己负责。 - gouessej

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接