The circumstances changed a lot for JDK9 so I was wondering a possible way it is to unmap a memory mapped file under Java 9 (JDK9).
One of the possible ways for <
JDK9 is here
The circumstances changed a lot for JDK9 so I was wondering a possible way it is to unmap a memory mapped file under Java 9 (JDK9).
One of the possible ways for <
JDK9 is here
Currently no special compiler parameter is necessary if you use something like:
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);
}
}
Note: "this can be dangerous unless you know everything about what is going on in the system". See comments.
Taken from GraphHopper that was inspired from Lucene its code. Furthmore it has code for Android too and has working solutions for older JDK9 versions where different compiler switches were necessary (see git history).
If you call this often better have a look into the Lucene code (which is a bit more tricky) which creates an 'uncleaner' once and just calls clean for the unmap.