Freeing MappedByteBuffer

While investigating a production bug that indicated that the operating system of a server running only a JVM continually ran out of memory under a specific set of circumstances, I discovered a very interesting idiosyncrasy of the JVM. Specifically, memory allocated with mmap through the MappedByteBuffer (the super class of DirectByteBuffer) does not get munmapped until the allocating MappedByteBuffer is garbage collected. Indeed, if you're looking, the JavaDocs make this behaviour clear:

A mapped byte buffer and the file mapping that it represents remain valid until the buffer itself is garbage-collected.

This behaviour has some serious implications including two that immediately come to mind:

  • Applications with long-lived (or prematurely tenured) MappedByteBuffers may exhibit slow off-heap leaks.

  • Applications with a large young generation (or low throughput) may not exhibit minor collections quickly enough to collect new, already-unreferenced MappedByteBuffers. This may result in a very rapid leak.

I hypothesise that both problems can be mitigated with careful consideration and design. As such, I feel that this idiosyncrasy is truly noteworthy and quite possibly the area of some future exploration. In the meantime, this topic is discussed and explained on the Java bug database and is subject to numerous duplications, each containing unique and useful information.