复制DirectByteBuffers OutOfMemoryError

时间:2012-06-07 15:11:09

标签: java java-native-interface

我打算使用DirectByteBuffers连接用C ++编写的第三方lib。

我担心the hadoop docs说:

  

使用幻像引用和引用队列对DirectByteBuffers进行垃圾回收。每隔一段时间,JVM就会检查引用队列并清除DirectByteBuffers。但是,由于在丢弃对DirectByteBuffer的所有引用后不会立即发生这种情况,因此使用DirectByteBuffers很容易使用OutOfMemoryError。

首先我不确定自OpenJDK 7以来DirectByteBuffers的所有实现是否都相同 似乎没有使用幻像引用,但依赖于应该具有性能损失的finalize方法。

其次,我尝试使用

复制OutOfMemoryError
public static void main(String[] args) {
    for(;;){
        ByteBuffer buff = ByteBuffer.allocateDirect(1000*1000);
    }
}

似乎一切都得到了适当的垃圾收集。如果在我的机器上使用

就是这种情况
java version "1.6.0_31"
Java(TM) SE Runtime Environment (build 1.6.0_31-b04-415-11M3635)
Java HotSpot(TM) 64-Bit Server VM (build 20.6-b01-415, mixed mode)

我可以依赖它,这将适用于所有其他机器和java版本> = 1.6?

由于

2 个答案:

答案 0 :(得分:2)

这是早期版本的Java 6中的一个错误。但是,JVM中包含的一个简单的解决方法是仅在触发System.gc()之后抛出OutOfMemoryError;现在,您可以通过禁用显式GC来模拟此问题。

Source for java.nio.Bits.reserveMemory(long)


我不等待GC清理直接内存或内存映射文件,而是使用内部API,这对于基于OpenJDK的JVM来说很好,例如热点。这可以通过减少虚假的Full GC来提高性能。

((DirectBuffer) buffer).cleaner().clean();

如果你有堆缓冲区,则cleaner()将返回null。

答案 1 :(得分:2)

This是关于此主题的精彩文章。

至于你的测试,像这样的简单测试并没有真正解决问题。当GC太落后时,潜在的问题就出现了。在这样的测试中,GC没有做任何其他事情,因此很可能不会出现问题。

相关问题