Java DirectByteBuffer包装器是否被垃圾收集?

Java DirectByteBuffer包装器是否被垃圾收集?,java,garbage-collection,bytebuffer,Java,Garbage Collection,Bytebuffer,我知道,当分配directbytebuffer时,它不会被垃圾收集,但我想知道的是包装对象是否被垃圾收集 例如,如果我分配了一个新的DirectByteBuffer dbb,然后使用dbb.duplicate()对其进行复制(浅复制),那么在同一内存块上会有两个包装器 那些包装纸要接受垃圾收集吗?如果我有 while(true){ DirectByteBuffer dbb2 = dbb.duplicate(); } 我最终会自己OOM吗?查看DirectByteBuffer的源代码,

我知道,当分配directbytebuffer时,它不会被垃圾收集,但我想知道的是包装对象是否被垃圾收集

例如,如果我分配了一个新的DirectByteBuffer dbb,然后使用dbb.duplicate()对其进行复制(浅复制),那么在同一内存块上会有两个包装器

那些包装纸要接受垃圾收集吗?如果我有

while(true){
    DirectByteBuffer dbb2 = dbb.duplicate();
} 

我最终会自己OOM吗?

查看DirectByteBuffer的源代码,它只返回一个新实例,所以不,你不会自己OOM


只要代码的其余部分没有保留对原始
dbb
的引用,那么该对象将正常地被垃圾收集。额外的
dbb2
对象在不再有任何引用(即while循环的结束)时也会被垃圾收集。

直接
ByteBuffer
对象与任何其他对象一样:它可以被垃圾收集

ByteBuffer
对象为GC'd时,直接缓冲区使用的内存将被释放(这不是为
ByteBuffer
明确规定的,而是在
MappedByteBuffer
的文档中暗示的)

有趣的是,当您用直接缓冲区填充了虚拟内存空间,但堆中仍然有很多空间时。事实证明(至少在Sun JVM上),在分配直接缓冲区时耗尽虚拟空间将触发Java堆的GC。它可以收集未引用的直接缓冲区并释放其虚拟内存


如果您在64位计算机上运行,您应该使用
-XX:MaxDirectMemorySize
,这会对您可以分配的缓冲区数量设置上限(并且在达到该限制时还会触发GC)。

在Sun JDK中,由创建的
java.nio.DirectByteBuffer
-有一个类型为
Sun.misc.Cleaner
的字段,这延伸了

当收集此
清理器
(请记住,
PhantomReference
的子类型)并即将移动到关联的
引用队列
,通过嵌套类型
ReferenceHandler
运行的与集合相关的线程对
Cleaner
实例有一个特殊的案例处理:它向下转换并调用
Cleaner#clean()
,最终返回到调用
DirectByteBuffer$Deallocator#run()
,这反过来会调用
不安全#空闲内存(long)
。哇

它相当迂回,我很惊讶没有看到
Object\finalize()
的任何使用。Sun开发人员一定有理由将其与收集和引用管理子系统更紧密地联系在一起

简而言之,只要垃圾回收器有机会注意到放弃,并且其引用处理线程通过上述调用取得进展,就不会因为放弃对
DirectByteBuffer
实例的引用而耗尽内存

分配directbytebuffer时,它不受垃圾的约束 收藏


你从哪里得到这个主意的?这是不对的。你把它们和MappedBytebuffer混在一起了吗?

实际上,DirectByteBuffer及其本机内存可能会被垃圾收集。它使用PhantomReference释放本机分配的内存。使用DirectByteBuffers如何帮助垃圾收集暂停,ala TerraCotta的BigMemory?@Li Pi:因为您可以在一个直接缓冲区中存储大量序列化Java对象。请注意,如果您使用
-XX:+DisableExplicitGC
,那么您可能会遇到更多
OutOfMemory
错误。分配尝试保留内存,若不能,则调用
System.gc()
,以触发
PhantomReference
的回收。