Difference in Used, Committed and Max Heap Memory

Solution 1:

From the Java Doc of MemoryUsage,

getUsed is:

the amount of used memory in bytes

getCommitted()

Returns the amount of memory in bytes that is committed for the Java virtual machine to use. This amount of memory is guaranteed for the Java virtual machine to use.

getMax()

Returns the maximum amount of memory in bytes that can be used for memory management. This method returns -1 if the maximum memory size is undefined.

This amount of memory is not guaranteed to be available for memory management if it is greater than the amount of committed memory. The Java virtual machine may fail to allocate memory even if the amount of used memory does not exceed this maximum size.

Solution 2:

First used < committed < max, and the unit of measure for all of them is bytes

  • init: the initial amount of memory that the JVM requested from the operating system at startup.
    • this is controlled by the -Xms cli option of the java command. See 2
  • used: amount of memory that is actually in use, so the memory consumed by all objects including the objects that are not reachable but haven't been garbaged collected yet.
    • it can be lower than init
  • committed: amount of memory that is reserved at the operating system level for the JVM process at the moment.
    • It can be equal or greater than the used, the JVM can request/allocated more memory from the OS and not really use it, but the OS is reserving that memory for the java process anyway.
    • it can go down, it maybe be even lower than init because the JVM can release memory back to the operating system.
    • if the JVM needs more memory will try to allocate more from the OS and then the committed will go up, but it's always possible that the OS runs of memory even if the amount of memory requested is lower that max
    • if you are trying to create new objects and the used < committed then the JVM does not need to request more memory from the OS and thus is guaranteed that it will succeed.
    • if you are trying to create new objects and the total amount of memory will go over committed then the JVM needs to allocate more memory from the OS before creating the object, that is not guaranteed to succeed (the OS may also run out of memory)
  • max: the maximum amount of memory that the JVM will ever try to request / allocate from the operating system
    • controlled by the -Xmx cli options. See 2
    • it is not guaranteed that the JVM will be able to allocate this much, the operating system may run out of memory because other processes reserved it.

So in the OP example

  • used is 3.8G
  • committed and max are 8.6G

that means that the JVM can allocate objects in the heap up to 8.6G and that is guaranteed, it won't have to ask the operating system for that since it was already allocated. If the JVM at some point requires more memory than that, because it needs to allocate more objects and it can't release any memory via garbage collection then it will fail with OOM since 8.6G is already the max it's allowed to request (I guess because it was started with -Xmx8600M.