Java - 何时发布直接缓冲区? [英] Java - When does direct buffer released?

查看:158
本文介绍了Java - 何时发布直接缓冲区?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因为它不属于jvm堆& gc,什么时候发布?或者,它一直持续到流程终止?

Since it's out of jvm heap & gc, when does it released? Or, it remain until process termination?

我已经检查过:

  • how to garbage collect a direct buffer java
  • Deallocating Direct Buffer Native Memory in Java for JOGL
  • ByteBuffer.allocate() vs. ByteBuffer.allocateDirect()

但所有答案都很模糊,没有明确回答,是否有明确答案?至少对于 64位Linux 上的 Java 8

But all the answers are blur, none answered it explicitly, does there have a clear answer? At least for Java 8 on 64-bit Linux.

推荐答案

DirectByteBuffer 不使用旧的Java终结器。相反,它使用内部 sun.misc.Cleaner API。它创建新线程并将 PhantomReference 存储到每个 DirectByteBuffer 创建(除了重复和切片,它们引用主缓冲区) 。当 DirectByteBuffer 变为幻像可达时(也就是说,不再存在对字节缓冲区的强,弱或弱引用),垃圾回收器会看到这个,它将此缓冲区添加到 ReferenceQueue ,它由 Cleaner 线程处理。因此应该发生三个事件:

DirectByteBuffer does not use old Java finalizers. Instead, it uses internal sun.misc.Cleaner API. It creates new thread and stores a PhantomReference to every DirectByteBuffer created (except duplicates and slices which refer to the primary buffer). When the DirectByteBuffer becomes phantom-reachable (that is, no strong, soft or weak references to the byte buffer exist anymore) and garbage collector sees this, it adds this buffer to the ReferenceQueue which is processed by Cleaner thread. So three events should occur:


  • DirectByteBuffer 变为幻像可达。

  • 执行垃圾收集(在单独的线程中), DirectByteBuffer 收集Java对象并将一个条目添加到 ReferenceQueue

  • 清洁线程到达此条目并运行已注册的清理操作(在这种情况下,它是 java.nio.DirectByteBuffer。 Deallocator object),这个动作最终释放了本机内存。

  • DirectByteBuffer becomes phantom-reachable.
  • Garbage collection is performed (in separate thread), DirectByteBuffer Java object is collected and an entry is added to the ReferenceQueue.
  • Cleaner thread reaches this entry and runs the registered clean-up action (in this case, it's java.nio.DirectByteBuffer.Deallocator object), this action finally frees the native memory.

所以一般来说你无法保证它被释放了。如果Java堆中有足够的内存,则可能无法长时间激活垃圾收集器。即使它是幻像可达,Cleaner线程也可能需要一些时间才能达到此条目。它可能忙于处理也使用Cleaner API的先前对象。但请注意,部分解决方法是在JDK中实现的:如果您之前创建新的 DirectByteBuffer 并分配了太多的直接内存,则可能会显式调用垃圾收集器以强制执行先前放弃的释放缓冲区。参见 Bits.reserveMemory() (从 DirectByteBuffer 构造函数调用)详细信息。

So in general you have no guarantee when it's freed. If you have enough memory in the Java heap, garbage collector may not be activated for a long time. Also even when it's phantom-reachable, Cleaner thread may need some time to reach this entry. It might be busy processing previous objects which also used the Cleaner API. Note however that partial work-around is implemented in JDK: if you create new DirectByteBuffer and allocated too much direct memory before, garbage collector might be called explicitly to enforce deallocation of previously abandoned buffers. See Bits.reserveMemory() (called from DirectByteBuffer constructor) for details.

请注意,在Java-9中,内部 Cleaner API已得到纠正并发布以供一般使用:现在它是 java.lang.ref .Cleaner 。阅读JavaDoc,您可以获得更多详细信息。

Note that in Java-9 the internal Cleaner API was rectified and published for general use: now it's java.lang.ref.Cleaner. Reading the JavaDoc you may get more details how it works.

这篇关于Java - 何时发布直接缓冲区?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆