将max和min JVM堆大小设置为相同是否合适?

时间:2011-07-28 17:18:16

标签: java jvm

目前在我们的测试环境中,max和min JVM堆大小设置为相同的值,基本上与专用服务器机器允许我们的应用程序一样多。这是性能的最佳配置还是让JVM的范围更好?

5 个答案:

答案 0 :(得分:26)

彼得的答案是正确的,因为-Xms在启动时被分配,并且它将长到-Xmx(最大堆大小),但它对他的方式有点误导已经措辞了他的答案。 (对不起彼得,我知道你知道这件事很冷)。

设置 ms == mx 可以有效地关闭此行为。虽然这在旧JVM中是一个好主意 ,但现在不再是这样了。增加和缩小堆允许JVM适应内存压力的增加,同时通过在内存压力降低时缩小堆来减少暂停时间。有时,此行为无法为您提供所期望的性能优势,在这些情况下,最好设置 mx == ms 。 当堆超过98%时间收集并且集合无法恢复超过2%时,会抛出 OOME 。如果你没有达到最大堆大小,那么JVM将会增长,以便你超越这个界限。除非您的堆达到最大堆大小并且满足定义OutOfMemoryError的其他条件,否则启动时不能有OutOfMemoryError

自我发布以来发表的评论。我不知道 JMonitor blog 条目正在显示什么,但这是来自PSYoung收集器。

size_t desired_size = MAX2(MIN2(eden_plus_survivors, gen_size_limit()),
                           min_gen_size());

我可以进行更多挖掘,但我敢打赌,我发现代码在ParNewPSOldGen以及CMS Tenured实现中具有相同的用途。事实上,除非有Concurrent Mode Failure,否则CMS不太可能返回内存。在CMF的情况下,串行收集器将运行并且应该包含一个压缩,之后堆的顶部很可能是干净的,因此有资格被释放。

答案 1 :(得分:8)

设置-Xms的主要原因是在启动时需要某个堆。 (防止在启动时发生OutOfMemoryErrors。)如上所述,如果您需要启动堆以匹配最大堆,那么您将匹配它。否则你真的不需要它。只是要求应用程序占用它可能最终需要的更多内存。在负载测试和使用应用程序的同时观察内存使用情况(分析)应该让您对将其设置为需要的内容有一个良好的感觉。但是在启动时将它们设置为相同并不是更糟糕的事情。对于我们的很多应用程序,我实际上从最初(启动)的128,256或512开始,最大为1千兆字节(这适用于非应用程序服务器应用程序)。

刚刚在堆栈溢出上找到了这个问题,这也可能有用side-effect-for-increasing-maxpermsize-and-max-heap-size。值得一看。

答案 2 :(得分:4)

AFAIK,将两者设置为相同的大小都会消除堆大小调整的额外步骤,如果您非常了解将要使用多少堆,那么这可能对您有利。此外,具有较大的堆大小会将GC调用减少到几次发生的程度。在我目前的项目(交易风险分析)中,我们的风险引擎同时具有XmxXms相同的值(大约8Gib)。这确保即使在调用引擎一整天之后,几乎不会发生GC。

另外,我发现了一个有趣的讨论here

答案 3 :(得分:2)

服务器应用肯定yes。拥有如此多的记忆但没有使用它有什么意义呢? (如果你不使用存储单元,不能省电)

JVM喜欢记忆。对于给定的应用程序,JVM具有的内存越多,它执行的GC就越少。最好的部分是更多的物体会死亡,而且会减少任期。

特别是在服务器启动期间,负载甚至高于正常情况。在这个阶段为服务器提供一个小内存可以解决问题。

答案 4 :(得分:1)

从我在http://java-monitor.com/forum/showthread.php?t=427看到的内容 正在测试的JVM从Xms设置开始,但是会释放它不需要的内存,并且在需要时将它带到Xmx标记。

除非你最初需要一大块专门用于大内存消费者的内存,否则投入高Xms = Xmx并没有多大意义。看起来即使使用Xms = Xmx

也会发生释放和分配