DirectBuffer,解除分配

时间:2017-10-07 21:56:46

标签: java garbage-collection direct-buffer

我分配了一个直接缓冲区:

ByteBuffer directBuffer = ByteBuffer.allocateDirect(1024);

我已经读过:

Deallocating Direct Buffer Native Memory in Java for JOGL

但它没有直接回答。

总结:

  1. 当GC启动并且directbuffer未被引用时,GC会发布directbuffer。在链接的帖子中写道:
  2.   

    当你知道直接NIO缓冲区对你没用时,你   必须使用sun.misc.Cleaner释放其本机内存   (StaxMan是对的)并调用clean()(与Apache Harmony除外),调用   free()(使用Apache Harmony)或使用更好的公共API来做到这一点   (也许在Java> = 1.9,AutoCleaning扩展AutoCloseable?)。

    但我没有看到如何显式释放内存块。好的,存在sun.misc.Cleaner和什么?:

    Cleaner c = new Cleaner()

    1. 使用DirectBuffer而不是Unsafe.allocateMemory的目的是什么。


    2.   

      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,不是吗?

2 个答案:

答案 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