Java 如何选择jvm堆大小?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1651225/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how to choose the jvm heap size?
提问by LB40
What i usually do concerning the jvm heap size is setting the max value really high to avoid the infamous OutOfMemoryException.
关于 jvm 堆大小,我通常做的是将最大值设置得非常高,以避免臭名昭著的 OutOfMemoryException。
However, this strategy (or lack of strategy) doesn't seem to be really smart. :-).
然而,这种策略(或缺乏策略)似乎并不真正聪明。:-)。
My question is how to choose the min and max values, and the difference between the two (should max-min be small or big?). For instance, from here:
我的问题是如何选择最小值和最大值,以及两者之间的差异(max-min 应该小还是大?)。例如,从这里:
if the initial heap is too small, the Java application startup becomes slow as the JVM is forced to perform garbage collection frequently until the heap has grown to a more reasonable size. For optimal startup performance you should set the initial heap size to the same as the maximum heap size.
如果初始堆太小,Java 应用程序启动会变慢,因为 JVM 被迫频繁执行垃圾收集,直到堆增长到更合理的大小。为了获得最佳启动性能,您应该将初始堆大小设置为与最大堆大小相同。
thanks.
谢谢。
采纳答案by Bob Cross
My question is how to choose the min and max values, and the difference between the two (should max-min be small or big?)
我的问题是如何选择最小值和最大值,以及两者之间的差异(max-min 应该小还是大?)
Short answer:don't guess, profile your application.
简短回答:不要猜测,分析您的应用程序。
jconsole can give you useful high-level datasuch as a feeling for the main resident set vs. the transient data that we normally allocate and garbage collect. What you'll see if you look at the memory tab of that display is usually something like a sawtooth. The lower corner of the sawteeth is about where I would normally set the heap minimum whereas I would use the peak or slope of the sawteeth to experiment with a heap maximum. If your teeth are very steep, you might consider a big heap just to delay the garbage collection. However, if they aren't, you could try a smaller heap maximum to see if that might leave more resources for other processes on your machine (for example).
jconsole 可以为您提供有用的高级数据,例如主要驻留集与我们通常分配和垃圾收集的瞬态数据的感觉。如果您查看该显示器的内存选项卡,您将看到的通常类似于锯齿。锯齿的下角大约是我通常设置堆最小值的位置,而我将使用锯齿的峰值或斜率来试验堆最大值。如果您的牙齿非常陡峭,您可能会考虑使用大堆来延迟垃圾收集。但是,如果不是,您可以尝试使用较小的堆最大值,以查看是否会为您机器上的其他进程留下更多资源(例如)。
You should also consider the server VMas that will cause different garbage collection behavior.
您还应该考虑服务器 VM,因为它会导致不同的垃圾收集行为。
All that said, you should also use a more detailed tool such as jvisualvm to profile the memory usage of your process. It's possible that you have a memory leak or greedy allocator that you could tune or eliminate. That would completely change your heap needs.
尽管如此,您还应该使用更详细的工具,例如jvisualvm 来分析进程的内存使用情况。您可能存在可以调整或消除的内存泄漏或贪婪分配器。这将完全改变您的堆需求。
回答by Robert Greiner
The right answer is: there is no right answereach project is different and you will have to fine-tune your heap size configuration on a per-project basis. I would start small and gradually increase the heap size until your application is running as intended.
正确答案是:没有正确答案,每个项目都不同,您必须在每个项目的基础上微调堆大小配置。我会从小处开始,逐渐增加堆大小,直到您的应用程序按预期运行。
You are right, setting a huge max value is not a good idea.
你是对的,设置一个巨大的最大值不是一个好主意。
回答by Jé Queue
You should enable GC logging and check to see where your OOM is ocurring.
您应该启用 GC 日志记录并检查您的 OOM 发生在哪里。
-verbose:gc
-Xloggc:gc.log
-XX:+PrintGCTimeStamps
-XX:+PrintGCDetails
You may be experiencing perm space limits, adjust via -XX:MaxPermSize=YYYm
您可能会遇到烫发空间限制,请通过以下方式进行调整 -XX:MaxPermSize=YYYm
Anyway to answer your question, I start with no minimums and set the maximum relatively high. I then graph the gc log and find out where my stead state is; visually choose an above-average size for the various generations. Read it like a financial chart, you'll want to see good spread in the new generations and a consistent growth and collection in the tenured generation. As mentioned also graph your perm space to make sure you're not constantly increasing.
无论如何,要回答您的问题,我从没有最小值开始,并将最大值设置得相对较高。然后我绘制 gc 日志并找出我的稳定状态在哪里;在视觉上为各代选择高于平均水平的尺寸。像财务图表一样阅读它,您会希望看到新生代的良好传播以及老一代的持续增长和收藏。如前所述,还要绘制您的烫发空间,以确保您不会不断增加。
GC tuning is an art, in no way a science.
GC 调优是一门艺术,绝不是一门科学。
回答by RMorrisey
If you are experiencing an OOME, I would actually start by increasing the max memory as much as you can, and see if that resolves the issue. Let your machine soak up the performance problem, first. If the problem persists, then you can look into performance diagnostics to identify bottlenecks and work on those areas where your app might be leaking or might be hogging the most memory.
如果您遇到 OOME,我实际上会首先尽可能多地增加最大内存,然后看看是否能解决问题。首先让您的机器解决性能问题。如果问题仍然存在,那么您可以查看性能诊断以识别瓶颈并在您的应用程序可能泄漏或可能占用最多内存的区域进行处理。
Jeff Atwood has a nice article on CodingHorror that explains this attitude; the most cost-effective solution to a performance problem is to throw hardware (or in this case, increased memory resources) at the problem, before investing developer time in troubleshooting:
Jeff Atwood 有一篇关于 CodingHorror 的好文章解释了这种态度;解决性能问题的最具成本效益的解决方案是在开发人员投入时间进行故障排除之前,将硬件(或在这种情况下,增加内存资源)用于解决问题:
回答by Pascal Thivent
Indeed, setting a huge max value blindly is not really a good idea (measure, don't guess) and this strategy will lead to very long "stop the world" major GCs which might not be desirable from a user experience point of view (always keep in mind that "the bigger the heap, the longer the major GC").
事实上,盲目地设置一个巨大的最大值并不是一个好主意(测量,不要猜测),而且这种策略会导致很长的“停止世界”主要 GC,从用户体验的角度来看这可能是不可取的(始终牢记“堆越大,主要 GC 的时间越长”)。
That said, there is no generic answer to your question, every application has different needs. Actually, I'd suggest to profile yourapplication and tune the heap to find a good compromise between (major) GC frequency and (major) GC duration while minimizing the response time to the end user. I warmly suggest to read this great blog post(and all others) from Kirk Pepperdine for further details.
也就是说,您的问题没有通用的答案,每个应用程序都有不同的需求。实际上,我建议您分析您的应用程序并调整堆,以在(主要)GC 频率和(主要)GC 持续时间之间找到一个很好的折衷方案,同时最大限度地减少对最终用户的响应时间。我热烈建议阅读Kirk Pepperdine 的这篇很棒的博客文章(以及所有其他文章)以获取更多详细信息。
Just to answer the min and max value part, I always use the same values (for better startup performances and better reproducibility).
只是为了回答最小值和最大值部分,我总是使用相同的值(为了更好的启动性能和更好的再现性)。
回答by John
It's a very bad idea to "ignore the -Xms parameter" as there are generally other applications and processes running on the same box. You want your application to start up with the maximum amount of RAM allocated, so if it fails, it fails while you're watching the start up logs, and not at 4:00AM when another application has taken up additional RAM on the box, and your JVM cannot grow in size.
“忽略 -Xms 参数”是一个非常糟糕的主意,因为通常在同一台机器上运行其他应用程序和进程。您希望您的应用程序以分配的最大 RAM 量启动,因此如果它失败,它会在您查看启动日志时失败,而不是在另一个应用程序在盒子上占用额外 RAM 的凌晨 4:00 时失败,并且您的 JVM 无法增长。
In short, ALWAYS set JVM min and mix size with the same value.
简而言之,始终将 JVM min 和混合大小设置为相同的值。