我打算使用DirectByteBuffers接口以C ++编写的第三方库。
我很担心the hadoop docs说:
通过使用幻像引用和引用队列对DirectByteBuffer进行垃圾回收。 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吗?
谢谢
最佳答案
这是Java 6早期版本中的一个错误。但是,JVM中包含的一个简单解决方法是仅在触发System.gc()之后才抛出OutOfMemoryError。现在,您可以通过禁用显式GC来模拟此问题。
Source for java.nio.Bits.reserveMemory(long)
我不等待GC清理直接内存或内存映射文件,而是使用内部API,该API对于基于OpenJDK的JVM很好,例如热点。通过减少虚假的完整GC来提高性能。
((DirectBuffer) buffer).cleaner().clean();
如果您有堆缓冲区,cleaner()将返回null。