Cassandra 中的堆内存默认分配

Heap Memory default allocation in Cassandra

根据 cassandra-env.sh 440G 总 RAM 的默认堆内存分配应为 32765M(JVM 切换到 64 位参考之前的最大 CAP)。

那么,为什么我查询"java -XX:+PrintCommandLineFlags -version"或"java -XX:+PrintFlagsFinal -version | grep -iE 'MaxHeapSize'"

时显示32210157568字节(30718M)

为什么有差异,大约2G。

仅供参考:jvm.options 文件是默认的并且使用 DSE 5.1.3。

java -XX:+PrintFlagsFinal和Cassandra没有关系,不知道你为什么要提cassandra-env.sh。无论如何,让我回答问题的主要部分。

在JDK8中,当不指定-Xmx时,最大堆大小估计为

MaxHeapSize = min(1/4 RAM, max_heap_for_compressed_oops)

在您的情况下,服务器有足够的 RAM,因此默认堆大小受基于零的压缩 oops 支持的最大可能大小限制,即 32 GB。

堆显然不能从零地址开始(空页由OS保留),而default heap alignment是2MB,所以我们至少要减去2MB。

然后,JDK 更愿意在 HeapBaseMinAddress 处分配堆,这是 equal to 2 GB on Linux. This provides some space to grow the native heap of the process. For this reason JVM reduces 默认的最大堆大小 HeapBaseMinAddress

这就是为什么最终计算出的堆大小等于

32 GB - 2 MB - 2 GB = 32210157568

如果放弃从零开始压缩oops的要求,可以设置-XX:HeapBaseMinAddress=0。在这种情况下,计算出的堆大小将为

32 GB - 2MB = 32766 MB