目前在我们的测试环境中,max和min JVM堆大小设置为相同的值,基本上与专用服务器机器允许我们的应用程序一样多。这是性能的最佳配置还是让JVM的范围更好?
答案 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());
我可以进行更多挖掘,但我敢打赌,我发现代码在ParNew
和PSOldGen
以及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调用减少到几次发生的程度。在我目前的项目(交易风险分析)中,我们的风险引擎同时具有Xmx
和Xms
相同的值(大约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
也会发生释放和分配