Search code examples
cassandrajvmdatastax

Heap Memory default allocation in Cassandra


As per cassandra-env.sh the default heap memory allocation for a 440G Total RAM should be 32765M (Maximum CAP before JVM Swithches to 64 bit reference).

So, why is it showing 32210157568 bytes(30718M) when I query "java -XX:+PrintCommandLineFlags -version" or "java -XX:+PrintFlagsFinal -version | grep -iE 'MaxHeapSize'"

Why is there difference, of around 2G.

FYI: jvm.options files was default & using DSE 5.1.3.


Solution

  • java -XX:+PrintFlagsFinal has nothing to do with Cassandra, and I don't know why you mention cassandra-env.sh. Anyway, let me answer the main part of the question.

    In JDK 8, when -Xmx is not specified, the maximum heap size is estimated as

    MaxHeapSize = min(1/4 RAM, max_heap_for_compressed_oops)
    

    In your case the server has plently of RAM, so the default heap size is limited by the maximum possible size supported by zero-based compressed oops, that is, 32 GB.

    The heap obviously cannot start at zero address (null page is reserved by the OS), and the default heap alignment is 2 MB, so we must subtract at least 2 MB.

    Then, JDK prefers to allocate the heap at HeapBaseMinAddress, which is equal to 2 GB on Linux. This provides some space to grow the native heap of the process. For this reason JVM reduces the default maximum heap size by HeapBaseMinAddress.

    That's why the final computed heap size is equal to

    32 GB - 2 MB - 2 GB = 32210157568
    

    If you give up the requirement for the zero-based compressed oops, you may set -XX:HeapBaseMinAddress=0. In this case the computed heap size would be

    32 GB - 2MB = 32766 MB