Search code examples
javajvm

Understanding off heap memory , Unsafe and MaxDirectMemorySize for a java application


I have been confused about how the off heap-size is controlled by JVM, so I would ask following questions to better understand it.

  1. When people use Java Unsafe API to allocate off-heap memory within a Java application, what the jvm option that can be used to control the memory size that can be allocated by Unsafe? Is it -XX:MaxDirectMemorySize? Are there any other options that can also be used to control the size ?

  2. From the JVM memory layout view, there is an area called direct memory, then MaxDirectMemorySize is used to control the size of this area? and Unsafe is allocating memory from this area?

  3. What's the default off-heap size if -XX:MaxDirectMemorySize is not set.

  4. If Unsafe try to allocate more memory than the JVM allows(eg, larger than MaxDirectMemorySize), OOM still happen?


Solution

    1. -XX:MaxDirectMemorySize limits the amount of memory that can be allocated with ByteBuffer.allocateDirect. Although allocateDirect uses Unsafe.allocateMemory under the hood, MaxDirectMemorySize option has no effect on raw Unsafe calls.

      Unsafe.allocateMemory boils down to the malloc function from the standard library. HotSpot JVM has no options to limit the amount of "Unsafe" memory.

    2. Strictly speaking, "direct memory" is an abstraction. Typical JVM implementation has no a dedicated area for direct memory. As mentioned above, Unsafe.allocateMemory acquires memory from the system malloc call. On top of that, Direct Buffers count the allocated memory against MaxDirectMemorySize limit.

    3. If MaxDirectMemorySize option is not set, the maximum size of the allocated direct memory is limited to the maximum heap size, more precisely, to the value of Runtime.getRuntime().maxMemory().

    4. No, JVM does not limit Unsafe.allocateMemory. It is upon the Operating System to control these allocations.