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

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

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

刚刚发现这个关于堆栈溢出的问题,这也可能有助于副作用增加maxpermsize-and-max-heap-size 。 值得一看。

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

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

对于自我发布以来的评论。 我不知道JMonitor博客条目显示的是什么,但这是来自PSYoungcollections家。

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

我可以做更多的挖掘,但我敢打赌,我会在ParNewPSOldGen以及CMS Tenured实现中找到用于相同目的的代码。 事实上,除非出现Concurrent Mode Failure否则CMS不太可能返回内存。 在CMF的情况下,串行收集器将运行并且应该包括压缩,之后堆的顶部很可能是干净的,因此有资格被解除分配。

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

另外,我在这里发现了一个有趣的讨论。

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

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

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

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

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