我们有以下代码:
long buffer = ((DirectBuffer) ByteBuffer.allocateDirect(256)).address();
线程堆栈上似乎没有对直接缓冲区(作为对象)的引用。因此,这意味着该对象是幻像可达的。
- 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 - When does direct buffer released?
因此,分配的内存有可能被释放。然而,我们有一个指向该缓冲区的指针,类型为long
。因此,我们可能有 SIGSEGV 或类似的东西。
我的问题是:
这是否意味着我们以这种方式使用 DirectBuffer 会伤害自己?
最佳答案
您在这里对危险的假设是正确的,但有一个警告。
在包含的 ByteBuffer 对象符合垃圾回收条件后,可以随时释放直接缓冲区的后备缓冲区(释放 native 内存的确切时刻取决于实现,但通常大约在 ByteBuffer 的终结器运行时发生)。
从标准 Java 来看,这个“悬空指针”不会造成真正的问题,因为它和其他指针一样长,并且不能不安全地使用。当然,如果您将其传递给某些 native 或不安全代码并尝试将其用作指针,事情可能会崩溃。
关于java - 在java中释放直接缓冲区以及可能的陷阱,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49959378/