Problem
A Sonatype server application may report an ERROR with this specific logged stack trace:
java.lang.OutOfMemoryError: null
at java.base/jdk.internal.misc.Unsafe.allocateMemory(Unsafe.java:616)
at java.base/java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:122)
at java.base/java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:317)
As there can be many different types of OutOfMemoryError, in particular, this article is concerned with the unique attributes related to allocating direct memory:
- The exception is a
java.lang.OutOfMemoryError
- The exception message is reported as null
-
allocateMemory
is an attempt to allocate system direct memory -
allocateDirect
indicates the problem relates specifically to "direct" OS memory, which is entirely different from JVM Heap memory
A more complete example logged error for IQ Server:
2024-03-19 09:34:40,439+0000 ERROR [QuartzScheduler_Worker-4] com.sonatype.insight.brain.search.index.IndexService - null
java.lang.OutOfMemoryError: null
at java.base/jdk.internal.misc.Unsafe.allocateMemory(Unsafe.java:616)
at java.base/java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:122)
at java.base/java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:317)
at java.base/sun.nio.ch.Util.getTemporaryDirectBuffer(Util.java:242)
at java.base/sun.nio.ch.IOUtil.read(IOUtil.java:242)
at java.base/sun.nio.ch.FileChannelImpl.read(FileChannelImpl.java:223)
at java.base/sun.nio.ch.ChannelInputStream.read(ChannelInputStream.java:65)
at java.base/sun.nio.ch.ChannelInputStream.read(ChannelInputStream.java:107)
at java.base/sun.nio.ch.ChannelInputStream.read(ChannelInputStream.java:101)
at java.base/java.nio.file.Files.read(Files.java:3159)
at java.base/java.nio.file.Files.readAllBytes(Files.java:3213)
at com.sonatype.insight.brain.report.Report.fetch(Report.java:963)
at com.sonatype.insight.brain.report.Report.getEntry(Report.java:169)
...
Possible causes
The "null" message in the OutOfMemoryError line indicates that the system refused the allocation, for example, because there is not enough OS memory. The java.nio.file.Files.readAllBytes attempts to use the system's non-heap area (Direct Memory).
Solution
NOTE: If no "-XX:MaxDirectMemorySize" is specified, OpenJDK uses the same amount as Xmx for the maximum Direct Memory size, so please make sure Xmx size * 2 is less than 2/3 of physical RAM (as OS and file caches use some RAM)
- Increase the physical RAM so that the OS won't refuse the allocation.
- If there is plenty of RAM available, set "-XX:MaxDirectMemorySize=<larger than Xmx>" in the same place as you set "-Xmx=".
- If the above two workarounds are not doable, if Java 11 or Java 8u102 or higher is used, setting "-Djdk.nio.maxCachedBufferSize=<bytes>" with a small value (e.g., 1/1000 of MaxDirectMemorySize) might improve the Direct Memory area usage by the other threads.
Ref: https://bugs.openjdk.org/browse/JDK-8175230
However, if there is insufficient RAM, even with this setting, it could still cause the same OOME.