是什么让我的ByteBuffer免于被释放?

时间:2011-10-31 03:33:14

标签: java memory bytebuffer

我正在分配大量的字节缓冲区。在我完成它们之后,我将所有引用设置为null。这应该是释放字节缓冲区的“正确”方法吗?取消引用它并让GC清理它?我也打电话给System.gc()尝试帮助它。

无论如何,我创建了一堆缓冲区,尊重它们;但在“一段时间”后,我得到各种各样的内存错误:java.lang.OutOfMemoryError:直接缓冲内存

我可以增加MaxDirectMemorySize,但它只会延迟上述错误。

我99%肯定我没有任何引用旧的ByteBuffers的东西。有没有办法检查这个,看看仍然有一个ByteBuffer分配了什么?

4 个答案:

答案 0 :(得分:1)

您可以使用像Eclipse一样免费的工具来查看保留字节缓冲区的内容,让它进行一些堆转换分析。

我能想到的另一种方法是使用具有终结器方法的其他东西包装你的字节缓冲区。

此外,Systen.gc()不保证您需要执行终结器System.runFinalization()以增加可能性。

答案 1 :(得分:1)

将引用设置为null是让垃圾收集器完成该对象的正确方法。还必须有其他一些悬空参考。我发现找到内存泄漏的最佳工具是YourKit。一个非常好的免费替代方案是Visual VM from the JDK

请记住,slice()操作会创建一个引用第一个字节缓冲区的新字节缓冲区。

答案 2 :(得分:0)

这是旧版Java的问题。最新版本的Java 6将在抛出OutOfMemoryError之前调用System.gc()。如果您不想触发GC,可以使用

在Oracle / Sun JVM上手动释放直接内存
((DirectBuffer) buffer).cleaner().clean();

然而,这是一种更好的方法来自行回收直接缓冲液,所以这样做并不是那么重要。 (直接创建ByteBuffers相对昂贵)

答案 3 :(得分:0)

Direct java.nio.ByteBuffer is (by definition) stored outside of java heap space. It is not freed until GC runs on heap, and frees it. But you can imagine a situation where heap usage is low therefore it does not need GC, but non-heap memory gets allocated and runs out of bounds.

Based on very interesting read: http://www.ibm.com/developerworks/library/j-nativememory-linux/

The pathological case would be that the native heap becomes full and one or more direct ByteBuffers are eligible for GC (and could be freed to make some space on the native heap), but the Java heap is mostly empty so GC doesn't occur.