如何选择jvm堆的大小?

ni65a41a  于 2022-11-07  发布在  其他
关注(0)|答案(6)|浏览(129)

关于JVM堆大小,我通常做的是将max值设置得很高,以避免声名狼借的OutOfMemoryException。
然而,这种策略(或缺乏策略)似乎并不真正明智。
我的问题是如何选择最小值和最大值,以及两者之间的差值(max-min应该小还是大?)。例如,从here
如果初始堆太小,Java应用程序的启动速度会变慢,因为JVM会被迫频繁执行垃圾收集,直到堆增长到更合理的大小为止。要获得最佳启动性能,应将初始堆大小设置为与最大堆大小相同。
谢谢你的好意。

0kjbasz6

0kjbasz61#

我的问题是如何选择最小值和最大值,以及两者之间的差异(最大值-最小值应该小还是大?)

**简短回答:**不要猜测,请分析您的应用程序。

jconsole可以为您提供有用的高级数据,例如主驻留集与我们通常分配和垃圾收集的 transient 数据的感觉。如果您查看该显示的内存选项卡,您会看到通常类似锯齿的东西。锯齿的下角大约是我通常设置堆最小值的地方,而我将使用锯齿的峰值或斜率来试验堆最大值。如果您的齿非常陡峭,您可能会考虑使用一个大堆来延迟垃圾收集。但是,如果它们不是这样,您可以尝试使用一个较小的堆最大值,以查看是否会为计算机上的其他进程留下更多资源(例如)。
您还应该考虑server VM,因为它将导致不同的垃圾收集行为。
尽管如此,您还应该使用jvisualvm to profile the memory usage of your process等更详细的工具。可能存在内存泄漏或贪婪分配器,您可以对其进行调整或消除。这将完全改变您的堆需求。

oyjwcjzk

oyjwcjzk2#

您应该启用GC日志记录并检查OOM发生的位置。

-verbose:gc
-Xloggc:gc.log  
-XX:+PrintGCTimeStamps
-XX:+PrintGCDetails

您可能遇到烫发空间限制,请通过-XX:MaxPermSize=YYYm进行调整
无论如何,为了回答你的问题,我从没有最小值开始,把最大值设置得相对较高,然后画出gc日志,找出我的稳态在哪里;直观地选择一个高于平均水平的尺寸。就像读一张财务图表一样,你会希望看到新一代的头发有很好的分布,而老一代的头发有稳定的增长和收集。如前所述,还要画出你的烫发空间,以确保你不会不断地增加。
GC调优是一门艺术,绝不是一门科学。

4dbbbstv

4dbbbstv3#

实际上,盲目地设置一个巨大的最大值并不是一个好主意(测量,不要猜测),这种策略将导致非常长的“停止世界”主要GC,从用户体验的Angular 来看,这可能是不可取的(始终记住“堆越大,主要GC越长”)。
也就是说,对于您的问题没有通用的答案,每个应用程序都有不同的需求。实际上,我建议您分析您的应用程序并调整堆,以便在(主要)GC频率和(主要)GC持续时间之间找到一个很好的折衷方案,同时最大限度地缩短对最终用户的响应时间。我强烈建议您阅读Kirk Pepperdine的这篇很棒的blog post(以及所有其他文章)以了解更多细节。
为了回答最小值和最大值部分,我总是使用相同的值(为了更好的启动性能和更好的再现性)。

bsxbgnwa

bsxbgnwa4#

正确的答案是:没有正确的答案每个项目都是不同的,您必须根据每个项目对堆大小配置进行微调。我会从小规模开始,然后逐渐增加堆大小,直到应用程序按预期运行。
你说得对,设置一个巨大的最大值并不是一个好主意。

vs91vp4v

vs91vp4v5#

如果你遇到了OOME,我会尽可能地增加最大内存,看看这样是否能解决问题。首先让你的机器吸收性能问题。如果问题仍然存在,你可以查看性能诊断,找出瓶颈,并在应用可能泄漏或占用最多内存的地方工作。
Jeff Atwood在CodingHorror上有一篇很好的文章解释了这种态度;对性能问题最具成本效益的解决方案是在将开发人员的时间投入到故障排除之前,先投入硬件(或者在这种情况下,增加存储器资源)来解决问题:
http://www.codinghorror.com/blog/archives/001198.html

r6l8ljro

r6l8ljro6#

“忽略-Xms参数”是一个非常糟糕的主意,因为通常有其他应用程序和进程在同一个机器上运行。您希望您的应用程序以分配的最大RAM量启动,因此如果它失败,它会在您查看启动日志时失败,而不是在凌晨4:00时,另一个应用程序占用了机器上的额外RAM,您的JVM无法增加大小。
简而言之,“始终”将JVM最小值和混合大小设置为相同的值。

相关问题