由于它不在jvm heap&gc中,何时发布?还是一直保留到流程终止?
但是所有答案都是模糊的,没有一个明确的答案,是否有明确的答案?至少适用于 64位Linux 上的 Java 8 。 __
DirectByteBuffer
不使用旧的Java终结器。相反,它使用内部sun.misc.Cleaner
API。它创建一个新线程并存储PhantomReference
到每个DirectByteBuffer
创建的线程中(除了重复和切片指的是主缓冲区)。当DirectByteBuffer
变成
幻影可到达的
(也就是说,不再存在对字节缓冲区的强引用,软引用或弱引用)并且垃圾回收器看到了这一点时,它将此缓冲区添加到ReferenceQueue
由Cleaner
线程处理的。因此应该发生三个事件:
DirectByteBuffer
变得幻影可达。DirectByteBuffer
收集Java对象并将一个条目添加到中ReferenceQueue
。java.nio.DirectByteBuffer.Deallocator
对象),该操作最终释放了本机内存。因此,总的来说,您无法保证它何时被释放。如果Java堆中有足够的内存,则垃圾收集器可能很长时间没有激活。同样,即使它是幻影可达的,清理线程也可能需要一些时间才能到达此条目。可能正在忙于处理也使用了Cleaner
API的先前对象。但是请注意,部分变通方法是在JDK中实现的:如果您之前创建了新的DirectByteBuffer
并且分配了太多的直接内存,则可能会显式调用垃圾回收器以强制释放先前废弃的缓冲区。有关详细信息,请参见Bits.reserveMemory()
(从DirectByteBuffer
构造函数调用)。
请注意,在Java-9中,内部Cleaner
API已更正并发布以供一般使用:现在是java.lang.ref.Cleaner
。阅读JavaDoc,您可能会获得更多有关其工作原理的详细信息。
问题内容: 在编写用于OpenGL库的Matrix类时,我遇到了一个问题,即使用Java数组还是使用Buffer策略存储数据(JOGL为Matrix操作提供直接缓冲区复制)。为了对此进行分析,我编写了一个小型性能测试程序,该程序比较了Arrays vs Buffers和Direct Buffers上循环和批量操作的相对速度。 我想在这里与您分享我的结果(因为我发现它们很有趣)。请随时发表评论和/或
问题内容: 使用Java 注释的最佳实践是什么?为什么? 用注解标记每个覆盖的方法似乎是过大的。是否存在某些编程情况要求使用和其他不应该使用的情况? 问题答案: 每次你重写一种方法都有两个好处时使用它。这样做是为了使你能够利用编译器检查的优势,以确保你认为自己确实覆盖了某个方法。这样,如果你犯了拼写错误的方法名称或不正确匹配参数的常见错误,将会警告你方法实际上并没有像你认为的那样覆盖。其次,它使你
问题内容: 我有以下代码,旨在读取目录并将其压缩到tar.gz归档文件中。当我将代码部署到服务器上并使用一批文件对其进行测试时,它可以在前几个测试批处理中使用,但是在第4批或第5批处理之后,它将始终如一地为我提供java.lang.OutOfMemoryError:即使直接缓冲内存文件批处理大小保持不变,并且堆空间看起来不错。这是代码: } 这是一个例外: 我认为有一个缓冲区内存泄漏,因为它在前4
正在为以下内容编写javadoc: 但是,将缓冲的输入流传入真的是一个问题吗?因此: 是否将is缓冲到bis中,或者java是否检测到is已缓冲并设置bis=is?如果是,不同的缓冲区大小是否会有所不同?如果没有,为什么不呢<注意:我说的是输入流,但实际上这个问题也适用于输出流
这是我在这里的第一个问题,我对Java很陌生,如果这是一个愚蠢的问题,请原谅。 我正在使用JavaDocs和注释从内部“记录”我的应用程序的预期行为,但我只是好奇在一个永远不会返回null的方法上使用是否合适或良好,但可能是由于未来的开发人员错误。 谢谢。
问题内容: 我有一个内存泄漏,我已经将其隔离到错误配置的直接字节缓冲区。 GC收集包含这些缓冲区但不处理缓冲区本身的对象。如果实例化包含缓冲区的瞬态对象足够多,则会得到以下令人鼓舞的消息: 我一直在寻找这个问题,显然 和 不工作。 问题答案: 我怀疑您的应用程序某处有对ByteBuffer实例的引用,这阻止了它被垃圾回收。 直接ByteBuffer的缓冲内存是在普通堆之外分配的(以便GC不会移