繁体   English   中英

堆大小大于 -Xmx

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM