[英]Heap size is greater than -Xmx
我使用-Xms256m
和-Xmx256m
JVM options将初始和最大 Java 堆大小设置为 256MB。 GC 日志(使用-XX:+PrintHeapAtGC
)指出堆大小为251904K
(246MB),小于最小堆大小-Xms256m
(请参阅日志的最后一行)。 但是,这是因为声明的堆大小是可用堆大小,不包括可用空间。
当我手动从空间内存中包含不可用的时,派生的堆大小为262656K
(256.5MB),略大于最大堆大小-Xmx
(512KB):
[heap size] = [eden space size] + [from space size] + [to space size] + [OldGen size]
262656K = 66048K + 10752K + 10752K + 175104K
为什么堆大小略大于最大堆大小-Xmx
?
首先它看起来很奇怪,但像往常一样没有魔法。 找到答案的唯一方法是更深入:到openjdk 源代码。 只需结帐并尝试 grep: grep -r "Xmx" .
会有很多测试,但它们对我们来说并不有趣。 两个文件可以帮助我们:/vm/runtime/arguments.cpp 和 /vm/memory/collectorPolicy.cpp
让我们看看arguments.cpp:只有简单的参数解析,例如对于-Xmx256M
,它将类似于result = 256 * 1024 * 1024
(我有一些内联)。 所以我们的问题没有答案。
但是这里初始化了变量MaxHeapSize
,所以我们可以试着找到它。 MaxHeapSize
的实际用法可以在我们的 /vm/memory/collectorPolicy.cpp(其中Xmx
仅在注释中使用)中找到,其中所有堆生成大小都由某些策略选择。
如果我们跳过所有细节,我们会发现堆中的所有区域都应该对齐,并且区域的大小取决于比率参数。
生成比率的默认 JVM 参数是-XX:NewRatio=2
(年轻代:老一代大小的比例)和-XX:SurvivorRatio=8
(伊甸园:幸存者代的比例)。 但是堆大小并不总是能被 3、9 或其他东西整除,所以应该有一些四舍五入。 而且,正如我之前提到的,总是应该有一些对齐。
所以,最后的答案是:这些尺寸是满足世代比例和对齐条件的唯一可能尺寸。 这些值的总和并不总是可能等于Xmx
参数值。
如果您有兴趣的细节,你可以找到四舍五入逻辑-XX:NewRatio
这里的方法scale_by_NewRatio_aligned
。 尝试自己找到关于-XX:SurvivorRatio
的相同逻辑:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.