Class MMapDirectory
- java.lang.Object
- 
- org.apache.lucene.store.Directory
- 
- org.apache.lucene.store.BaseDirectory
- 
- org.apache.lucene.store.FSDirectory
- 
- org.apache.lucene.store.MMapDirectory
 
 
 
 
- 
- All Implemented Interfaces:
- Closeable,- AutoCloseable
 
 public class MMapDirectory extends FSDirectory File-basedDirectoryimplementation that uses mmap for reading, andFSDirectory.FSIndexOutputfor writing.NOTE: memory mapping uses up a portion of the virtual memory address space in your process equal to the size of the file being mapped. Before using this class, be sure your have plenty of virtual address space, e.g. by using a 64 bit JRE, or a 32 bit JRE with indexes that are guaranteed to fit within the address space. On 32 bit platforms also consult MMapDirectory(Path, LockFactory, long)if you have problems with mmap failing because of fragmented address space. If you get an OutOfMemoryException, it is recommended to reduce the chunk size, until it works.This class supports preloading files into physical memory upon opening. This can help improve performance of searches on a cold page cache at the expense of slowing down opening an index. See setPreload(BiPredicate)for more details.Due to this bug in OpenJDK, MMapDirectory's IndexInput.close()is unable to close the underlying OS file handle. Only when GC finally collects the underlying objects, which could be quite some time later, will the file handle be closed.This will consume additional transient disk usage: on Windows, attempts to delete or overwrite the files will result in an exception; on other platforms, which typically have a "delete on last close" semantics, while such operations will succeed, the bytes are still consuming space on disk. For many applications this limitation is not a problem (e.g. if you have plenty of disk space, and you don't rely on overwriting files on Windows) but it's still an important limitation to be aware of. This class supplies the workaround mentioned in the bug report, which may fail on non-Oracle/OpenJDK JVMs. It forcefully unmaps the buffer on close by using an undocumented internal cleanup functionality. If UNMAP_SUPPORTEDistrue, the workaround will be automatically enabled (with no guarantees; if you discover any problems, you can disable it by using system propertyENABLE_UNMAP_HACK_SYSPROP).For the hack to work correct, the following requirements need to be fulfilled: The used JVM must be at least Oracle Java / OpenJDK. In addition, the following permissions need to be granted to lucene-core.jarin your policy file:- permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
- permission java.lang.RuntimePermission "accessClassInPackage.sun.misc";
 Starting with Java 19 this class will use the modern MemorySegmentAPI which allows to safely unmap (if you discover any problems with this preview API, you can disable it by using system propertyENABLE_MEMORY_SEGMENTS_SYSPROP).Starting with Java 21 on some platforms like Linux and MacOS X, this class will invoke the syscall madvise()to advise how OS kernel should handle paging after opening a file. For this to work, Java code must be able to call native code. If this is not allowed, a warning is logged. To enable native access for Lucene in a modularized application, pass--enable-native-access=org.apache.lucene.coreto the Java command line. If Lucene is running in a classpath-based application, use--enable-native-access=ALL-UNNAMED.NOTE: Accessing this class either directly or indirectly from a thread while it's interrupted can close the underlying channel immediately if at the same time the thread is blocked on IO. The channel will remain closed and subsequent access to MMapDirectorywill throw aClosedChannelException. If your application uses eitherThread.interrupt()orFuture.cancel(boolean)you should use the legacyRAFDirectoryfrom the Lucenemiscmodule in favor ofMMapDirectory.NOTE: If your application requires external synchronization, you should not synchronize on the MMapDirectoryinstance as this may cause deadlock; use your own (non-Lucene) objects instead.- See Also:
- Blog post about MMapDirectory
 
- 
- 
Field SummaryFields Modifier and Type Field Description static BiPredicate<String,IOContext>ALL_FILESArgument forsetPreload(BiPredicate)that configures all files to be preloaded upon opening them.static BiPredicate<String,IOContext>BASED_ON_LOAD_IO_CONTEXTArgument forsetPreload(BiPredicate)that configures files to be preloaded upon opening them if they use theIOContext.LOADI/O context.static longDEFAULT_MAX_CHUNK_SIZEDefault max chunk size: 16 GiBytes for 64 bit Java 19 / 20 / 21 JVMs 1 GiBytes for other 64 bit JVMs 256 MiBytes for 32 bit JVMsstatic StringENABLE_MEMORY_SEGMENTS_SYSPROPThis sysprop allows to control ifMemorySegmentAPI should be used on supported Java versions.static StringENABLE_UNMAP_HACK_SYSPROPThis sysprop allows to control the workaround/hack for unmapping the buffers from address space after closingIndexInput.static BiPredicate<String,IOContext>NO_FILESArgument forsetPreload(BiPredicate)that configures no files to be preloaded upon opening them.static StringUNMAP_NOT_SUPPORTED_REASONifUNMAP_SUPPORTEDisfalse, this contains the reason why unmapping is not supported.static booleanUNMAP_SUPPORTEDtrue, if this platform supports unmapping mmapped files.- 
Fields inherited from class org.apache.lucene.store.FSDirectorydirectory
 - 
Fields inherited from class org.apache.lucene.store.BaseDirectoryisOpen, lockFactory
 
- 
 - 
Constructor SummaryConstructors Constructor Description MMapDirectory(Path path)Create a new MMapDirectory for the named location andFSLockFactory.getDefault().MMapDirectory(Path path, int maxChunkSize)Deprecated.useMMapDirectory(Path, long)instead.MMapDirectory(Path path, long maxChunkSize)Create a new MMapDirectory for the named location andFSLockFactory.getDefault().MMapDirectory(Path path, LockFactory lockFactory)Create a new MMapDirectory for the named location.MMapDirectory(Path path, LockFactory lockFactory, int maxChunkSize)Deprecated.useMMapDirectory(Path, LockFactory, long)instead.MMapDirectory(Path path, LockFactory lockFactory, long maxChunkSize)Create a new MMapDirectory for the named location, specifying the maximum chunk size used for memory mapping.
 - 
Method SummaryAll Methods Static Methods Instance Methods Concrete Methods Deprecated Methods Modifier and Type Method Description longgetMaxChunkSize()Returns the current mmap chunk size.booleangetPreload()Deprecated.This information is no longer reliable now that preloading is more granularly configured via a predicate.booleangetUseUnmap()Deprecated.useUNMAP_SUPPORTEDIndexInputopenInput(String name, IOContext context)Creates an IndexInput for the file with the given name.voidsetPreload(boolean preload)Deprecated.UsesetPreload(BiPredicate)instead which provides more granular control.voidsetPreload(BiPredicate<String,IOContext> preload)Configure which files to preload in physical memory upon opening.voidsetUseUnmap(boolean useUnmapHack)Deprecated, for removal: This API element is subject to removal in a future version.Please use new system propertyENABLE_UNMAP_HACK_SYSPROPinsteadstatic booleansupportsMadvise()Returns true, if MMapDirectory uses the platform'smadvise()syscall to advise how OS kernel should handle paging after opening a file.- 
Methods inherited from class org.apache.lucene.store.FSDirectoryclose, createOutput, createTempOutput, deleteFile, deletePendingFiles, ensureCanRead, fileLength, fsync, getDirectory, getPendingDeletions, listAll, listAll, open, open, rename, sync, syncMetaData, toString
 - 
Methods inherited from class org.apache.lucene.store.BaseDirectoryensureOpen, obtainLock
 - 
Methods inherited from class org.apache.lucene.store.DirectorycopyFrom, getTempFileName, openChecksumInput
 
- 
 
- 
- 
- 
Field Detail- 
ALL_FILESpublic static final BiPredicate<String,IOContext> ALL_FILES Argument forsetPreload(BiPredicate)that configures all files to be preloaded upon opening them.
 - 
NO_FILESpublic static final BiPredicate<String,IOContext> NO_FILES Argument forsetPreload(BiPredicate)that configures no files to be preloaded upon opening them.
 - 
BASED_ON_LOAD_IO_CONTEXTpublic static final BiPredicate<String,IOContext> BASED_ON_LOAD_IO_CONTEXT Argument forsetPreload(BiPredicate)that configures files to be preloaded upon opening them if they use theIOContext.LOADI/O context.
 - 
DEFAULT_MAX_CHUNK_SIZEpublic static final long DEFAULT_MAX_CHUNK_SIZE Default max chunk size:- 16 GiBytes for 64 bit Java 19 / 20 / 21 JVMs
- 1 GiBytes for other 64 bit JVMs
- 256 MiBytes for 32 bit JVMs
 
 - 
ENABLE_UNMAP_HACK_SYSPROPpublic static final String ENABLE_UNMAP_HACK_SYSPROP This sysprop allows to control the workaround/hack for unmapping the buffers from address space after closingIndexInput. By default it is enabled; set tofalseto disable the unmap hack globally. On command line pass-Dorg.apache.lucene.store.MMapDirectory.enableUnmapHack=falseto disable.- See Also:
- Constant Field Values
- NOTE: This API is for internal purposes only and might change in incompatible ways in the next release.
 
 - 
ENABLE_MEMORY_SEGMENTS_SYSPROPpublic static final String ENABLE_MEMORY_SEGMENTS_SYSPROP This sysprop allows to control ifMemorySegmentAPI should be used on supported Java versions. By default it is enabled; set tofalseto use legacyByteBufferimplementation. On command line pass-Dorg.apache.lucene.store.MMapDirectory.enableMemorySegments=falseto disable.- See Also:
- Constant Field Values
- NOTE: This API is for internal purposes only and might change in incompatible ways in the next release.
 
 - 
UNMAP_SUPPORTEDpublic static final boolean UNMAP_SUPPORTED true, if this platform supports unmapping mmapped files.
 - 
UNMAP_NOT_SUPPORTED_REASONpublic static final String UNMAP_NOT_SUPPORTED_REASON ifUNMAP_SUPPORTEDisfalse, this contains the reason why unmapping is not supported.
 
- 
 - 
Constructor Detail- 
MMapDirectorypublic MMapDirectory(Path path, LockFactory lockFactory) throws IOException Create a new MMapDirectory for the named location. The directory is created at the named location if it does not yet exist.- Parameters:
- path- the path of the directory
- lockFactory- the lock factory to use
- Throws:
- IOException- if there is a low-level I/O error
 
 - 
MMapDirectorypublic MMapDirectory(Path path) throws IOException Create a new MMapDirectory for the named location andFSLockFactory.getDefault(). The directory is created at the named location if it does not yet exist.- Parameters:
- path- the path of the directory
- Throws:
- IOException- if there is a low-level I/O error
 
 - 
MMapDirectory@Deprecated public MMapDirectory(Path path, int maxChunkSize) throws IOException Deprecated.useMMapDirectory(Path, long)instead.Create a new MMapDirectory for the named location andFSLockFactory.getDefault(). The directory is created at the named location if it does not yet exist.- Throws:
- IOException
 
 - 
MMapDirectorypublic MMapDirectory(Path path, long maxChunkSize) throws IOException Create a new MMapDirectory for the named location andFSLockFactory.getDefault(). The directory is created at the named location if it does not yet exist.- Parameters:
- path- the path of the directory
- maxChunkSize- maximum chunk size (for default see- DEFAULT_MAX_CHUNK_SIZE) used for memory mapping.
- Throws:
- IOException- if there is a low-level I/O error
 
 - 
MMapDirectory@Deprecated public MMapDirectory(Path path, LockFactory lockFactory, int maxChunkSize) throws IOException Deprecated.useMMapDirectory(Path, LockFactory, long)instead.Create a new MMapDirectory for the named location andFSLockFactory.getDefault(). The directory is created at the named location if it does not yet exist.- Throws:
- IOException
 
 - 
MMapDirectorypublic MMapDirectory(Path path, LockFactory lockFactory, long maxChunkSize) throws IOException Create a new MMapDirectory for the named location, specifying the maximum chunk size used for memory mapping. The directory is created at the named location if it does not yet exist.Especially on 32 bit platform, the address space can be very fragmented, so large index files cannot be mapped. Using a lower chunk size makes the directory implementation a little bit slower (as the correct chunk may be resolved on lots of seeks) but the chance is higher that mmap does not fail. On 64 bit Java platforms, this parameter should always be large (like 1 GiBytes, or even larger with recent Java versions), as the address space is big enough. If it is larger, fragmentation of address space increases, but number of file handles and mappings is lower for huge installations with many open indexes. Please note: The chunk size is always rounded down to a power of 2. - Parameters:
- path- the path of the directory
- lockFactory- the lock factory to use, or null for the default (- NativeFSLockFactory);
- maxChunkSize- maximum chunk size (for default see- DEFAULT_MAX_CHUNK_SIZE) used for memory mapping.
- Throws:
- IOException- if there is a low-level I/O error
 
 
- 
 - 
Method Detail- 
setUseUnmap@Deprecated(forRemoval=true) public void setUseUnmap(boolean useUnmapHack) Deprecated, for removal: This API element is subject to removal in a future version.Please use new system propertyENABLE_UNMAP_HACK_SYSPROPinsteadThis method is retired, see deprecation notice!- Throws:
- UnsupportedOperationException- as setting cannot be changed
 
 - 
getUseUnmap@Deprecated public boolean getUseUnmap() Deprecated.useUNMAP_SUPPORTEDReturnstrue, if the unmap workaround is enabled.- See Also:
- setUseUnmap(boolean)
 
 - 
setPreloadpublic void setPreload(BiPredicate<String,IOContext> preload) Configure which files to preload in physical memory upon opening. The default implementation does not preload anything. The behavior is best effort and operating system-dependent.- Parameters:
- preload- a- BiPredicatewhose first argument is the file name, and second argument is the- IOContextused to open the file
- See Also:
- ALL_FILES,- NO_FILES
 
 - 
setPreload@Deprecated public void setPreload(boolean preload) Deprecated.UsesetPreload(BiPredicate)instead which provides more granular control.Configure whether to preload files on thisMMapDirectoryinto physical memory upon opening. The behavior is best effort and operating system-dependent.
 - 
getPreload@Deprecated public boolean getPreload() Deprecated.This information is no longer reliable now that preloading is more granularly configured via a predicate.Return whether files are loaded into physical memory upon opening.- See Also:
- setPreload(BiPredicate)
 
 - 
getMaxChunkSizepublic final long getMaxChunkSize() Returns the current mmap chunk size.- See Also:
- MMapDirectory(Path, LockFactory, long)
 
 - 
openInputpublic IndexInput openInput(String name, IOContext context) throws IOException Creates an IndexInput for the file with the given name.- Specified by:
- openInputin class- Directory
- Parameters:
- name- the name of an existing file.
- Throws:
- IOException- in case of I/O error
 
 - 
supportsMadvisepublic static boolean supportsMadvise() Returns true, if MMapDirectory uses the platform'smadvise()syscall to advise how OS kernel should handle paging after opening a file.
 
- 
 
-