[ https://issues.apache.org/jira/browse/LUCENE-4755?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Uwe Schindler closed LUCENE-4755. --------------------------------- > Unmap MMapIndexInput's in a delayed way, and avoid WeakReference usage. > ----------------------------------------------------------------------- > > Key: LUCENE-4755 > URL: https://issues.apache.org/jira/browse/LUCENE-4755 > Project: Lucene - Core > Issue Type: Improvement > Components: core/store > Reporter: Kristofer Karlsson > Priority: Major > > (Most of this is shamelessly borrowed from Uwe Schindler) > It would be nice to move away from using WeakReference to clean up clones. > Instead, the clones could depend on the master by using a shared boolean > closed-flag. > In order to ensure visibility of this value, or at least make it less likely > to crash, we could delay the unmapping operation. > Rough suggestion of changes: > {code:java} > public class ByteBufferUnmapper { > /** > * <code>true</code>, if this platform supports unmapping mmapped files. > */ > public static final boolean UNMAP_SUPPORTED; > private static final ScheduledExecutorService SCHEDULED_EXECUTOR_SERVICE = > Executors.newSingleThreadScheduledExecutor(new > NamedThreadFactory("unmapper-")); > static { > boolean v = false; > try { > Class.forName("sun.misc.Cleaner"); > Class.forName("java.nio.DirectByteBuffer") > .getMethod("cleaner"); > v = true; > } catch (Exception e) { > // Do nothing > } finally { > UNMAP_SUPPORTED = v; > } > } > public static void unmap(final ByteBuffer buffer) throws IOException { > try { > AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() { > public Object run() throws Exception { > Method getCleanerMethod = buffer.getClass().getMethod("cleaner"); > getCleanerMethod.setAccessible(true); > final Object cleaner = getCleanerMethod.invoke(buffer); > if (cleaner != null) { > cleaner.getClass().getMethod("clean").invoke(cleaner); > } > return null; > } > }); > } catch (PrivilegedActionException e) { > final IOException ioe = new IOException("unable to unmap the mapped > buffer"); > ioe.initCause(e.getCause()); > throw ioe; > } > } > public static void unmapLater(final ByteBuffer buffer, long delay, TimeUnit > unit) { > SCHEDULED_EXECUTOR_SERVICE.schedule(new Runnable() { > public void run() { > try { > unmap(buffer); > } catch (IOException e) { > e.printStackTrace(); > } > } > }, delay, unit); > } > } > {code} > {code:java} > // MMapDirectory > final void cleanMapping(final ByteBuffer buffer) throws IOException { > if (useUnmapHack) { > ByteBufferUnmapper.unmapLater(buffer, 10, TimeUnit.SECONDS); > } > } > {code} > {code:java} > // MMapIndexInput > @Override > public short readShort() throws IOException { > if (closed[0]) { > throw new AlreadyClosedException("MMapIndexInput already closed: " + > this); > } > {code} > {code:java} > @Override > public void close() throws IOException { > try { > if (isClone || buffers == null) return; > closed[0] = true; > > // make local copy, then un-set early > final ByteBuffer[] bufs = buffers; > > for (final ByteBuffer b : bufs) { > cleanMapping(b); > } > } finally { > unsetBuffers(); > } > } > {code} -- This message was sent by Atlassian Jira (v8.3.4#803005) --------------------------------------------------------------------- To unsubscribe, e-mail: issues-unsubscr...@lucene.apache.org For additional commands, e-mail: issues-h...@lucene.apache.org