堆大小大于-Xmx

时间:2015-02-08 03:28:04

标签: java memory garbage-collection jvm heap

我使用-Xms256m and -Xmx256m JVM options将初始和最大Java堆大小设置为256MB。 GC日志(使用-XX:+PrintHeapAtGC)表明堆大小为251904K(246MB),即smaller than the minimum heap size, -Xms256m(请参阅最后一行日志)。但是,这是因为the stated heap size is the available heap size,不包括the unavailable from space

当我从空间内存中手动包含不可用的时,派生的堆大小为262656K(256.5MB),略大于大于最大堆大小{{ 1}} (512KB):

-Xmx

为什么堆大小略大于最大堆大小[heap size] = [eden space size] + [from space size] + [to space size] + [OldGen size] 262656K = 66048K + 10752K + 10752K + 175104K

1 个答案:

答案 0 :(得分:5)

首先它看起来很奇怪,但像往常一样没有魔法。找到答案的唯一方法是深入探讨openjdk sources。只需结帐并尝试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 here的逻辑。 尝试自己找到关于-XX:SurvivorRatio的相同逻辑:)