Java GC如何清除直接字节缓冲区,因为IBM Docs说它确实如此。

时间:2016-10-19 04:19:41

标签: java garbage-collection jvm nio bytebuffer

我假设,我理解Bytebuffer和DirectByteBuffer是如何区别的,直到我阅读IBM文档的一篇文章,提到:

“Direct ByteBuffer对象自动清理其本机缓冲区,但只能作为Java堆GC的一部分”

https://www.ibm.com/developerworks/library/j-nativememory-linux/

现在我无法理解这一行,因为它说DirectByteBuffer作为Java堆GC的一部分进行清理。

IFAIK,Java Heap GC只在java堆中进行清理(未分配DirectByteBuffer)。 它(GC)不知道本机内存(分配了DirectByteBuffer)。

请帮助我理解这一行,或者我的理解是否有差距

3 个答案:

答案 0 :(得分:5)

当你创建java.nio.DirectByteBuffer的实例时,你基本上有2个部分:

  • 类型java.nio.DirectByteBuffer的常用java对象,在堆上分配
  • 您想要的实际字节缓冲区,由上述Java对象的构造函数从堆中分配

此外,java.nio.DirectByteBuffer的构造函数注册了一个类型为java.nio.DirectByteBuffer.Deallocator的runnable,它是一个私有静态类。当GC清除此java.nio.DirectByteBuffer实例时,将执行此runnable。此Deallocator的任务是释放本机字节缓冲区。 RTFS! :)

答案 1 :(得分:0)

  

它说DirectByteBuffer作为Java堆GC的一部分进行清理。

不,不。它说'Direct ByteBuffer对象自动清理它们的本机缓冲区,但只能作为Java堆GC的一部分。根本不是一回事。

  

IFAIK,Java Heap GC只在java堆中清理

正确,但IBM正在谈论直接ByteBuffers进行清理,而不是GC。

  

(未分配DirectByteBuffer)。

没有DirectByteBuffer之类的东西。有直接ByteBuffers 在堆上分配,除了它们的直接部分,它是一个本机字节数组。

  

它(GC)不知道本机内存(分配了DirectByteBuffer)。

再次出错,见上文。

这没有什么神秘之处。直接ByteBuffers可以有finalize()方法,在GC调用时调用本机字节数组的清理。

答案 2 :(得分:0)

  

Java Heap GC只在java堆中清理

在HotSpot JVM中,当清理DirectByteBuffer时,与之关联的内存被释放或取消映射。

注意:这与作为外部资源(如套接字,文件流,GUI组件)代理的其他对象没有什么不同。

不同的是资源不可关闭。这可能由于多种原因而无法使用,这很可能是因为在释放内存区域后访问内存区域可能会损坏内存或导致JVM崩溃。使用Hotspot JVM,可以使用

确定性地释放/取消映射内存
((DirectBuffer) buffer).cleaner().clean();

但是,这是没有记录的,a)不同的JVM,b)使用风险自负,c)将来可能无法使用。