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

时间:2022-09-29 00:16:56

Currently in our testing environment the max and min JVM heap size are set to the same value, basically as much as the dedicated server machine will allow for our application. Is this the best configuration for performance or would giving the JVM a range be better?

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

5 个解决方案

#1


7  

Main reason to set the -Xms is for if you need a certain heap on start up. (Prevents OutOfMemoryErrors from happening on start up.) As mentioned above, if you need the startup heap to match the max heap is when you would match it. Otherwise you don't really need it. Just asks the application to take up more memory that it may ultimately need. Watching your memory use over time (profiling) while load testing and using your application should give you a good feel for what to need to set them to. But it isn't the worse thing to set them to the same on start up. For a lot of our apps, I actually start out with something like 128, 256, or 512 for min (startup) and one gigabyte for max (this is for non application server applications).

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

Just found this question on stack overflow which may also be helpful side-effect-for-increasing-maxpermsize-and-max-heap-size. Worth the look.

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

#2


24  

Peter 's answer is correct in that -Xms is allocated at startup and it will grow up to -Xmx (max heap size) but it's a little misleading in how he has worded his answer. (Sorry Peter I know you know this stuff cold).

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

Setting ms == mx effectively turns off this behavior. While this used to be a good idea in older JVMs, it is no longer the case. Growing and shrinking the heap allows the JVM to adapt to increases in pressure on memory yet reduce pause time by shrinking the heap when memory pressure is reduced. Sometimes this behavior doesn't give you the performance benefits you'd expect and in those cases it's best to set mx == ms. OOME is thrown when heap is more than 98% of time is spent collecting and the collections cannot recover more than 2% of that. If you are not at max heaps size then the JVM will simply grow so that you're beyond that boundaries. You cannot have an OutOfMemoryError on startup unless your heap hits the max heap size and meets the other conditions that define an OutOfMemoryError.

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

For the comments that have come in since I posted. I don't know what the JMonitor blog entry is showing but this is from the PSYoung collector.

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

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

I could do more digging about but I'd bet I'd find code that serves the same purpose in the ParNew and PSOldGen and CMS Tenured implementations. In fact it's unlikely that CMS would be able to return memory unless there has been a Concurrent Mode Failure. In the case of a CMF the serial collector will run and that should include a compaction after which top of heap would most likely be clean and therefore eligible to be deallocated.

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

#3


3  

AFAIK, setting both to the same size does away with the additional step of heap resizing which might be in your favour if you pretty much know how much heap you are going to use. Also, having a large heap size reduces GC invocations to the point that it happens very few times. In my current project (risk analysis of trades), our risk engines have both Xmx and Xms to the same value which pretty large (around 8Gib). This ensures that even after an entire day of invoking the engines, almost no GC takes place.

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

Also, I found an interesting discussion here.

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

#4


1  

Definitely yes for a server app. What's the point of having so much memory but not using it? (No it doesn't save electricity if you don't use a memory cell)

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

JVM loves memory. For a given app, the more memory JVM has, the less GC it performs. The best part is more objects will die young and less will tenure.

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

Especially during a server startup, the load is even higher than normal. It's brain dead to give server a small memory to work with at this stage.

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

#5


0  

From what I see here at http://java-monitor.com/forum/showthread.php?t=427 the JVM under test begins with the Xms setting, but WILL deallocate memory it doesn't need and it will take it upto the Xmx mark when it needs it.

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

Unless you need a chunk of memory dedicated for a big memory consumer initially, there's not much of a point in putting in a high Xms=Xmx. Looks like deallocation and allocation occur even with Xms=Xmx

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

#1


7  

Main reason to set the -Xms is for if you need a certain heap on start up. (Prevents OutOfMemoryErrors from happening on start up.) As mentioned above, if you need the startup heap to match the max heap is when you would match it. Otherwise you don't really need it. Just asks the application to take up more memory that it may ultimately need. Watching your memory use over time (profiling) while load testing and using your application should give you a good feel for what to need to set them to. But it isn't the worse thing to set them to the same on start up. For a lot of our apps, I actually start out with something like 128, 256, or 512 for min (startup) and one gigabyte for max (this is for non application server applications).

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

Just found this question on stack overflow which may also be helpful side-effect-for-increasing-maxpermsize-and-max-heap-size. Worth the look.

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

#2


24  

Peter 's answer is correct in that -Xms is allocated at startup and it will grow up to -Xmx (max heap size) but it's a little misleading in how he has worded his answer. (Sorry Peter I know you know this stuff cold).

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

Setting ms == mx effectively turns off this behavior. While this used to be a good idea in older JVMs, it is no longer the case. Growing and shrinking the heap allows the JVM to adapt to increases in pressure on memory yet reduce pause time by shrinking the heap when memory pressure is reduced. Sometimes this behavior doesn't give you the performance benefits you'd expect and in those cases it's best to set mx == ms. OOME is thrown when heap is more than 98% of time is spent collecting and the collections cannot recover more than 2% of that. If you are not at max heaps size then the JVM will simply grow so that you're beyond that boundaries. You cannot have an OutOfMemoryError on startup unless your heap hits the max heap size and meets the other conditions that define an OutOfMemoryError.

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

For the comments that have come in since I posted. I don't know what the JMonitor blog entry is showing but this is from the PSYoung collector.

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

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

I could do more digging about but I'd bet I'd find code that serves the same purpose in the ParNew and PSOldGen and CMS Tenured implementations. In fact it's unlikely that CMS would be able to return memory unless there has been a Concurrent Mode Failure. In the case of a CMF the serial collector will run and that should include a compaction after which top of heap would most likely be clean and therefore eligible to be deallocated.

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

#3


3  

AFAIK, setting both to the same size does away with the additional step of heap resizing which might be in your favour if you pretty much know how much heap you are going to use. Also, having a large heap size reduces GC invocations to the point that it happens very few times. In my current project (risk analysis of trades), our risk engines have both Xmx and Xms to the same value which pretty large (around 8Gib). This ensures that even after an entire day of invoking the engines, almost no GC takes place.

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

Also, I found an interesting discussion here.

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

#4


1  

Definitely yes for a server app. What's the point of having so much memory but not using it? (No it doesn't save electricity if you don't use a memory cell)

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

JVM loves memory. For a given app, the more memory JVM has, the less GC it performs. The best part is more objects will die young and less will tenure.

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

Especially during a server startup, the load is even higher than normal. It's brain dead to give server a small memory to work with at this stage.

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

#5


0  

From what I see here at http://java-monitor.com/forum/showthread.php?t=427 the JVM under test begins with the Xms setting, but WILL deallocate memory it doesn't need and it will take it upto the Xmx mark when it needs it.

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

Unless you need a chunk of memory dedicated for a big memory consumer initially, there's not much of a point in putting in a high Xms=Xmx. Looks like deallocation and allocation occur even with Xms=Xmx

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