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.