Suggested fix for JDK-4724038 (Add unmap method to MappedByteBuffer)
uschindler at apache.org
Wed Sep 9 16:22:04 UTC 2015
> As I thought, the problem for some seems to be non-prompt unmapping of
> mapped address space held by otherwise unreachable mapped byte buffers.
> The mapped address space doesn't live in the Java heap and doesn't
> represent a heap memory pressure, so GC doesn't kick-in automatically
> when one would like. One could help by manually triggering GC with
> System.gc() in such situations. The problem is how to detect such situations.
> Direct byte buffers (ByteBuffer.allocateDirect) maintain a count of bytes
> currently allocated and don't allow allocation of native memory beyond
> certain configured limit (-XX:MaxDirectMemorySize=<size>).
> Before throwing OutOfMemoryError, the ByteBuffer.allocateDirect()
> request tries it's best to free direct memory allocated by otherwise
> unreachable direct ByteBuffers (using System.gc() to trigger GC and helping
> process references).
FileChannel#map does the same (it tries to map, catches OOM, waits a second and tries again). But as described in my earlier mail this does not work as expected in newer GC implementations - this is why we see the issues like a JVM running for a week or longer without any full GC and then sitting on a Terabyte of address/diskspace space before getting unuseable. System#gc() is ignored in most environments, because it causes more havoc (full pauses) - especially if a full GC is otherwise rarely needed. I think this crazy try-catch-sleep-retry code should better be removed from FileChannel#map once the GC algorithms are fixed to take care of the heaviness of MappedByteBuffer (my proposal, the Annotation @sun.misc.Heavy...) and free it earlier.
In addition, I think Andrew Haley made some good comments about opportunities how to solve the problem.
More information about the core-libs-dev