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

发布于 2024-11-24 02:03:32 字数 302 浏览 2 评论 0原文

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

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

这些包装器是否会受到垃圾收集?如果我这样做,

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

我最终会 OOM 吗?

I understand that when a directbytebuffer is allocated, its not subject to garbage collection, but what I'm wondering is if the wrapping object is garbage collected.

For example, if I allocated a new DirectByteBuffer dbb, and then duplicated(shallow copied) it using dbb.duplicate(), I'd have two wrappers around the same chunk of memory.

Are those wrappers subject to garbage collection? If I did

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

Would I eventually OOM myself?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

疧_╮線 2024-12-01 02:03:33

在 Sun JDK 中,java.nio.DirectByteBuffer — 由 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 实例的引用而耗尽内存如上所述。

In the Sun JDK, a java.nio.DirectByteBuffer—created by ByteBuffer#allocateDirect(int)—has a field of type sun.misc.Cleaner, which extends java.lang.ref.PhantomReference.

When this Cleaner (remember, a subtype of PhantomReference) gets collected and is about to move into the associated ReferenceQueue, the collection-related thread running through the nested type ReferenceHandler has a special case treatment of Cleaner instances: it downcasts and calls on Cleaner#clean(), which eventually makes its way back to calling on DirectByteBuffer$Deallocator#run(), which in turn calls on Unsafe#freeMemory(long). Wow.

It's rather circuitous, and I was surprised to not see any use of Object#finalize() in play. The Sun developers must have had their reasons for tying this in even closer to the collection and reference management subsystem.

In short, you won't run out of memory by virtue of abandoning references to DirectByteBuffer instances, so long as the garbage collector has a chance to notice the abandonment and its reference handling thread makes progress through the calls described above.

彼岸花ソ最美的依靠 2024-12-01 02:03:33

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

ByteBuffer 对象被 GC 时,直接缓冲区使用的内存将被释放(这对于 ByteBuffer 没有明确说明,但在 的文档中隐含了>MappedByteBuffer)。

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

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

A direct ByteBuffer object is just like any other object: it can be garbage-collected.

The memory used by a direct buffer will be released when the ByteBuffer object is GC'd (this is not explicitly stated for ByteBuffer, but is implied by the documentation of MappedByteBuffer).

Where things get interesting is when you've filled your virtual memory space with direct buffers, but still have lots of room in the heap. It turns out that (at least on the Sun JVM), running out of virtual space when allocating a direct buffer will trigger a GC of the Java heap. Which may collect unreferenced direct buffers and free their virtual memory commitment.

If you're running on a 64-bit machine, you should use -XX:MaxDirectMemorySize, which puts an upper limit on the number of buffers that you can allocate (and also triggers GC when you hit that limit).

﹎☆浅夏丿初晴 2024-12-01 02:03:33

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

只要代码的其余部分不保留对原始 dbb 的引用,那么该对象就会像平常一样被垃圾收集。当不再有任何对它们的引用时(即 while 循环结束),额外的 dbb2 对象将类似地被垃圾收集。

Looking at the source code to DirectByteBuffer it just returns a new instance, so no, you won't OOM yourself.

As long as the rest of your code doesn't hold onto a reference to the original dbb then that object will get garbage collected as normal. The extra dbb2 objects will similarly get garbage collected when there is no longer any reference to them(ie, the end of the while loop).

非要怀念 2024-12-01 02:03:33

Java 对象和本机内存都被垃圾收集器同时释放。

但是,请注意,由于垃圾收集器在清理直接缓冲区方面效果不佳,因此最好分配和重用长期存在的直接缓冲区,而不是创建和放弃新的直接缓冲区。

Both the Java object and the native memory are freed at the same time by the garbage collector.

However, note that because the garbage collector doesn’t work well at cleaning up direct buffers, it’s best to allocate and reuse long-lived direct buffers instead of creating and abandoning new ones.

感情废物 2024-12-01 02:03:33

当分配 directbytebuffer 时,它不会产生垃圾
收藏

你从哪里得到这个想法的?这是不正确的。您是否将它们与 MappedByteBuffers 混淆了?

when a directbytebuffer is allocated, its not subject to garbage
collection

Where did you get that idea? It's not correct. Are you getting them mixed up with MappedByteBuffers?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文