我分配了一个直接缓冲区:
ByteBuffer directBuffer = ByteBuffer.allocateDirect(1024);
我已经读过:
Deallocating Direct Buffer Native Memory in Java for JOGL
但它没有直接回答。
总结:
directbuffer
未被引用时,GC会发布directbuffer
。在链接的帖子中写道:当你知道直接NIO缓冲区对你没用时,你 必须使用sun.misc.Cleaner释放其本机内存 (StaxMan是对的)并调用clean()(与Apache Harmony除外),调用 free()(使用Apache Harmony)或使用更好的公共API来做到这一点 (也许在Java> = 1.9,AutoCleaning扩展AutoCloseable?)。
但我没有看到如何显式释放内存块。好的,存在sun.misc.Cleaner
和什么?:
Cleaner c = new Cleaner()
使用DirectBuffer而不是Unsafe.allocateMemory
的目的是什么。
This solution(在此JEP中,仍然是草案,可能不是 Java 1.9中提供的非常有前景,我们不需要使用非 公共API。
public long memory(long index) { // The scope where the memory region is available // Implements AutoClosable but `close` can be called manually as well try (Scope scope = new NativeScope()) { // Allocate the actual memory area, in this case in the style of a "long-array" Pointer<Long> ptr = scope.allocate( NativeLibrary.createLayout(long.class), numElements); // Get the reference to a certain element Reference<Long> ref = ptr.offset(index).deref(); // Set a value to this element through the reference ref.set(Long.MAX_VALUE); // Read the value of an element return ref.get(); } }
它看起来像C ++中的smartpointers,不是吗?
答案 0 :(得分:1)
但我没有看到如何明确释放内存块。
目前你不能在java中因为它不安全。它可能导致免费使用后的错误。 使其安全的方法,例如虚拟记忆操作或安全点体操很难,可能会花费一些性能或者可能无法在所有平台上运行。
这不是不可能,但需要大量工作。请参阅JDK-4724038,其重复项和链接的邮件列表,了解多年来积累的提案。
使用DirectBuffer而不是Unsafe.allocateMemory的目的是什么。
安全访问可以传递给本机代码的稳定内存位置,无需复制,也不需要对象固定(热点不支持的内容)。
答案 1 :(得分:0)
你真的可以,但代码很奇怪。
// unmap the memory mapped buffer (wait gc cleans it up)
ReferenceQueue rq = new ReferenceQueue();
PhantomReference<ByteBuffer> ref = new PhantomReference<>(ref_out, rq);
ref_out = null;
while(rq.poll() == null) {
System.gc();
}
// all finalizers are finished... only phantom references left.
PhantomReference<PhantomReference> pref = new PhantomReference<>(ref, rq);
ref.clear();
ref = null;
while(rq.poll() == null) {
System.gc();
}
pref.clear();
干杯,
d