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
根据 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