在Java 9下取消映射mmapped文件的最佳方法是什么?

时间:2017-06-29 19:21:51

标签: mmap java-9

JDK9的情况发生了很大变化,所以我想知道在Java 9(JDK9)下取消映射内存映射文件的可行方法。

< JDK9的一种可能方式是here

1 个答案:

答案 0 :(得分:2)

目前,如果您使用以下内容,则不需要特殊的编译器参数:

public static void cleanMappedByteBuffer(final ByteBuffer buffer) {
 try {
   AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
      @Override
      public Object run() throws Exception {
           final Class<?> unsafeClass = Class.forName("sun.misc.Unsafe");
           // we do not need to check for a specific class, we can call the Unsafe method with any buffer class
           MethodHandle unmapper = MethodHandles.lookup().findVirtual(unsafeClass, "invokeCleaner",
               MethodType.methodType(void.class, ByteBuffer.class));
           // fetch the unsafe instance and bind it to the virtual MethodHandle
           final Field f = unsafeClass.getDeclaredField("theUnsafe");
           f.setAccessible(true);
           final Object theUnsafe = f.get(null);
           try {
               unmapper.bindTo(theUnsafe).invokeExact(buffer);
               return null;
           } catch (Throwable t) {
               throw new RuntimeException(t);
           }
      }      
   });
 } catch (PrivilegedActionException e) {
   throw new RuntimeException("Unable to unmap the mapped buffer", e);
 }
}

注意:&#34;除非您了解系统中发生的事情,否则这可能很危险。见评论。

取自GraphHopper的灵感来自Lucene its code。此外,它还具有适用于Android的代码,并且为旧版JDK9版本提供了可行的解决方案,其中需要不同的编译器开关(参见git历史记录)。

如果你通常更好地调用它,那么看看Lucene代码(这有点棘手)会创建一个“不清洁”的代码。一次,只需要为unmap调用clean。