Hi, > 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. Uwe