Java DirectByteBuffer包装器是垃圾收集的吗?

Li *_* Pi 11 java garbage-collection bytebuffer

我理解当分配一个directbytebuffer时,它不受垃圾收集的影响,但我想知道的是包装对象是否被垃圾收集.

例如,如果我分配了一个新的DirectByteBuffer dbb,然后使用dbb.duplicate()复制(浅层复制)它,我会在同一块内存中有两个包装器.

这些包装纸是否需要进行垃圾收集?如果我做了

while(true){
    DirectByteBuffer dbb2 = dbb.duplicate();
} 
Run Code Online (Sandbox Code Playgroud)

我最终会自己OOM吗?

seh*_*seh 14

在Sun JDK中,java.nio.DirectByteBuffer-aated是ByteBuffer#allocateDirect(int)一个类型的字段sun.misc.Cleaner,它扩展了java.lang.ref.PhantomReference.

当这个Cleaner(记住,一个子类型PhantomReference)被收集并即将进入关联时ReferenceQueue,通过嵌套类型运行的与集合相关的线程ReferenceHandlerCleaner实例进行了特殊处理:它向下转换并调用Cleaner#clean(),最终返回呼叫DirectByteBuffer$Deallocator#run(),然后呼吁Unsafe#freeMemory(long).哇.

这是相当迂回的,我很惊讶没有看到任何使用Object#finalize().Sun开发人员必须有理由将其与更接近集合和参考管理子系统联系起来.

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

  • 请注意,如果您使用`-XX:+ DisableExplicitGC`,那么使用`allocateDirect`可能会遇到更多`OutOfMemory`错误.分配尝试保留内存并调用`System.gc()`如果它不能触发'PhantomReference`的回收. (2认同)