public abstract class Unmapper
extends java.lang.Object
This is a tricky business. At Java 8 there is no good way to
unmap the memory mapped by a MappedByteBuffer.
The MappedByteBuffer javadocs say
"A mapped byte buffer and the file mapping that it represents remain
valid until the buffer itself is garbage-collected.",
and there is no explicit unmap method.
However, since the resources locked by memory mapping are separate
from the JVM heap, there is no guarantee that garbage collection will
happen even when mapped memory reaches crisis levels, and in practice
this can lead to cache thrashing and the OS locking up even when there
are many MappedByteBuffers without active references, at least on
some platforms (I see it on Scientific Linux 6.5 with 24Gb RAM, but
not SL 6.3 with 4Gb, but I'm not sure what the relevant differences are).
The best way around this is dependent on Java version.
Before about Java 22, the only way was using implementation-specific
classes in the sun.* namespace to do the unmapping.
This is not guaranteed to work on all J2SE implementations,
and moreover it risks a JVM crash if the buffer instance is used
after the umapping has been done. So use it WITH EXTREME CAUTION.
At Java 22 and later (previewed in Java 19?), public classes in the
java.lang.foreign package can be used for this purpose,
which is safe.
Provision of the default Unmapper instance, available from the
static getInstance() method, is therefore done using
reflection to provide an implementation that depends on the current JRE.
It is possible to specify a preference for how this is done among
the available options (or providing a custom Unampper implementation)
by use of the UNMAP_PROPERTY ("startable.unmap")
system property,
or programmatically using the setInstance method.
| Modifier and Type | Field and Description |
|---|---|
static Unmapper |
NOP
Unmapper instance that makes no attempt to reclaim resources.
|
static java.lang.String |
UNMAP_PROPERTY
Name of system property to control buffer unmapping ("startable.unmap").
|
| Modifier | Constructor and Description |
|---|---|
protected |
Unmapper()
Constructor.
|
| Modifier and Type | Method and Description |
|---|---|
static Unmapper |
getInstance()
Returns the standard instance of this class.
|
abstract UnmappableBuffer |
mapFile(java.nio.channels.FileChannel channel,
long offset,
int leng)
Creates an object that represents a read-only mapped region of a file,
and for which it is possible to attempt release of resources
at a later date.
|
void |
setInstance(Unmapper unmapper)
Sets the instance of this class that will be returned by
the
getInstance() method. |
public static final java.lang.String UNMAP_PROPERTY
sun": best-efforts sun.misc-based optioncleaner": sun.misc.Cleaner-based option
(available in Oracle Java 6 through Java 8)unsafe": sun.misc.Unsafe-based option
(available in Oracle Java 9 through Java 25?)memseg": java.lang.foreign.MemorySegment-based option
(available in approx Java 22 and later)none": no unmappingdefault": tries to use memseg,
then sun, then none,
depending on what's availableUnmapper
concrete subclass with a no-arg constructor.
If the property is not set, behaviour is as "default".
public static final Unmapper NOP
public abstract UnmappableBuffer mapFile(java.nio.channels.FileChannel channel, long offset, int leng) throws java.io.IOException
No explicit checking of the parameters is done by this method; helpful messages to users about bad parameter choices should be generated by the caller.
channel - file channeloffset - offset into file of mapped region startleng - number of bytes to mapjava.io.IOExceptionpublic static Unmapper getInstance()
UNMAP_PROPERTY has asked for something specific that
cannot be provided, a RuntimeException will be thrown.java.lang.RuntimeException - if an option has been explicitly chosen
that cannot be instantiatedpublic void setInstance(Unmapper unmapper)
getInstance() method.unmapper - default instance