简体   繁体   English

如何选择jvm堆大小?

[英]how to choose the jvm heap size?

What i usually do concerning the jvm heap size is setting the max value really high to avoid the infamous OutOfMemoryException. 我通常对jvm堆大小做的是将max值设置得非常高,以避免臭名昭着的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?). 我的问题是如何选择最小值和最大值,以及两者之间的差异(max-min应该小还是大?)。 For instance, from here : 例如,从这里

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. 如果初始堆太小,Java应用程序启动变慢,因为JVM被迫频繁执行垃圾收集,直到堆增长到更合理的大小。 For optimal startup performance you should set the initial heap size to the same as the maximum heap size. 为获得最佳启动性能,应将初始堆大小设置为与最大堆大小相同。

thanks. 谢谢。

My question is how to choose the min and max values, and the difference between the two (should max-min be small or big?) 我的问题是如何选择最小值和最大值,以及两者之间的差异(最大值应该小还是大?)

Short answer: don't guess, profile your application. 简短的回答:不要猜测,描述您的应用程序。

jconsole can give you useful high-level data such as a feeling for the main resident set vs. the transient data that we normally allocate and garbage collect. jconsole可以为您提供有用的高级数据,例如主要驻留集的感觉与我们通常分配的垃圾数据和垃圾收集。 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). 但是,如果不是,则可以尝试使用较小的堆最大值来查看是否可能为计算机上的其他进程留下更多资源(例如)。

You should also consider the server VM as 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 . 总而言之,您还应该使用更详细的工具(如jvisualvm)来分析流程的内存使用情况 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. 这将完全改变你的堆需求。

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; 然后我绘制gc日志图并找出我的替代状态; 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 tuning is an art, in no way a science. GC调整是一门艺术,绝不是一门科学。

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 your application 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. 其实,我建议来分析您的应用程序并调整堆找(大),GC的频率和(大)GC持续时间之间的良好折衷,同时尽量减少响应时间到最终用户。 I warmly suggest to read this great blog post (and all others) from Kirk Pepperdine for further details. 我热烈建议您阅读Kirk Pepperdine的这篇精彩博文 (以及其他所有文章 )以获取更多详细信息。

Just to answer the min and max value part, I always use the same values (for better startup performances and better reproducibility). 只是为了回答最小值和最大值部分,我总是使用相同的值(为了更好的启动性能和更好的再现性)。

The right answer is: there is no right answer each 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. 你是对的,设置一个巨大的最大值并不是一个好主意。

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. 如果您遇到OOME,我实际上会尽可能多地增加最大内存,看看是否能解决问题。 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. 如果问题仍然存在,那么您可以查看性能诊断以识别瓶颈,并处理应用程序可能泄漏或可能占用大部分内存的区域。

Jeff Atwood has a nice article on CodingHorror that explains this attitude; 杰夫阿特伍德有一篇关于CodingHorror的好文章解释了这种态度; 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: 对于性能问题,最具成本效益的解决方案是在将开发人员的时间投入到故障排除之前抛出硬件(或者在这种情况下,增加内存资源)。

http://www.codinghorror.com/blog/archives/001198.html http://www.codinghorror.com/blog/archives/001198.html

It's a very bad idea to "ignore the -Xms parameter" as there are generally other applications and processes running on the same box. “忽略-Xms参数”是一个非常糟糕的主意,因为通常在同一个盒子上运行其他应用程序和进程。 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. 您希望应用程序以分配的最大RAM量启动,因此如果失败,则在您查看启动日志时失败,而不是在凌晨4:00,当另一个应用程序占用了额外的RAM时,并且你的JVM不能增长。

In short, ALWAYS set JVM min and mix size with the same value. 简而言之,总是设置JVM min并将大小混合为相同的值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM