我以为,我理解如何Bytebuffer和DirectByteBuffer的区别,直到我读了一篇文章的IBM文档,提出:
“直接ByteBuffer对象自动清除其本机缓冲区,但只能作为Java堆GC的一部分执行此操作”
https://www.ibm.com/developerworks/library/j-nativememory-linux/
现在我不能理解这一行,因为它说DirectByteBuffer作为Java堆GC的一部分进行清理。
IFAIK,Java堆GC只在Java堆中进行清理(其中未分配DirectByteBuffer)。它(GC)不知道本机内存(其中分配了DirectByteBuffer)。
请帮助我理解这一行,或者如果我理解有差距
4条答案
按热度按时间n6lpvg4x1#
当您创建
java.nio.DirectByteBuffer
的示例时,实际上有两个部分:java.nio.DirectByteBuffer
的普通java对象,在堆上分配另外,
java.nio.DirectByteBuffer
的构造函数注册了一个java.nio.DirectByteBuffer.Deallocator
类型的runnable,它是一个私有静态类。当java.nio.DirectByteBuffer
的示例被GC清理时,这个runnable就会被执行。Deallocator
的任务就是释放本机字节缓冲区。RTFS!:)vu8f3i0k2#
对于11(可能是更高),在GC检测到DirectByteBuffer已变为幻影可达之后的某个时间,引用处理程序线程将运行DirectByteBuffer中的清除代码,该代码将释放本机内存区域。
您可以通过调用
Unsafe
来自己调用清理,如下所示:我确实觉得,如果可以的话,应该避免做这一切。
q3qa4bjr3#
Java堆GC仅在Java堆中执行清除
在HotSpot JVM中,清除DirectByteBuffer时,会释放或取消Map与相关联的内存。
注意:这与作为外部资源(如套接字、文件流、GUI组件)的代理的其他对象没有什么不同。
不同的是资源不是Closeable的。这可能是由于多种原因而不可用的,最有可能的原因是在内存区域被释放后访问它可能会损坏内存或使JVM崩溃。使用Hotspot JVM,可以使用
但是,这是未记录的,并且a)不同JVM之间不相同,B)使用风险自担,c)将来可能不可用。
lg40wkob4#
它说
DirectByteBuffer
将清理作为Java堆GC的一部分。不,它没有。它说“直接
ByteBuffer
对象自动清理它们的本机缓冲区,但 * 只能 * 作为Java堆GC的一部分这样做”。完全不是一回事。IFAIK、Java堆GC仅在Java堆中执行清理
正确,但是IBM说的是直接用
ByteBuffers
进行清理,而不是用GC。(其中
DirectByteBuffer
未分配)。没有
DirectByteBuffer
这样的东西,有直接的ByteBuffers
,它们 * 是 * 在堆上分配的,除了它们的直接部分,这是一个本机字节数组。它(GC)不知道本机内存(分配DirectByteBuffer的地方)。
又错了,见上文。
这并不神秘。直接
ByteBuffers
可以有一个finalize()
方法,当被GC调用时,该方法调用本机字节数组的清理。