0

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

我从hadoop 文档中担心说:

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

首先,我不确定 DirectByteBuffers 的所有实现是否都相同,因为OpenJDK 7 似乎没有使用幻像引用,而是依赖于应该有性能损失的 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吗?

谢谢

4

2 回答 2

2

This is a great article on the subject.

As for your test, simple tests like that don't really exercise the problem area. the potential issue arises when the GC gets too far behind. in a test like that, the GC isn't doing anything else so likely won't have problem keeping up.

于 2012-06-07T15:21:13.657 回答
2

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

java.nio.Bits.reserveMemory(long) 的源代码


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

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

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

于 2012-06-07T15:18:25.417 回答