如何选择 jvm 堆大小?
我通常对jvm堆大小所做的是将最大值设置得非常高,以避免臭名昭着的OutOfMemoryException。
然而,这种策略(或缺乏策略)似乎并不真正聪明。:-).
我的问题是如何选择最小值和最大值,以及两者之间的差异(max-min应该是小的还是大的?)。例如,从这里:
如果初始堆太小,Java 应用程序启动将变慢,因为 JVM 被迫频繁执行垃圾回收,直到堆增长到更合理的大小。为了获得最佳启动性能,应将初始堆大小设置为与最大堆大小相同。
谢谢。
我通常对jvm堆大小所做的是将最大值设置得非常高,以避免臭名昭着的OutOfMemoryException。
然而,这种策略(或缺乏策略)似乎并不真正聪明。:-).
我的问题是如何选择最小值和最大值,以及两者之间的差异(max-min应该是小的还是大的?)。例如,从这里:
如果初始堆太小,Java 应用程序启动将变慢,因为 JVM 被迫频繁执行垃圾回收,直到堆增长到更合理的大小。为了获得最佳启动性能,应将初始堆大小设置为与最大堆大小相同。
谢谢。
我的问题是如何选择最小值和最大值,以及两者之间的差异(max-min应该是小的还是大的?
简短的回答:不要猜,分析你的应用程序。
jconsole可以为您提供有用的高级数据,例如对主要驻留集的感觉与我们通常分配的瞬态数据和垃圾回收。如果您查看该显示器的内存选项卡,您将看到的内容通常类似于锯齿。锯齿的下角大约是我通常设置堆最小值的位置,而我将使用锯齿的峰值或斜率来试验堆最大值。如果你的牙齿非常陡峭,你可能会考虑一个大堆来延迟垃圾收集。但是,如果不是,则可以尝试较小的堆最大值,以查看这是否会为计算机上的其他进程留出更多资源(例如)。
还应考虑服务器 VM,因为这会导致不同的垃圾回收行为。
总而言之,您还应该使用更详细的工具(例如jvisualvm)来分析进程的内存使用情况。您可能有一个可以调整或消除的内存泄漏或贪婪的分配器。这将完全改变您的堆需求。
您应该启用 GC 日志记录并检查 OOM 的位置。
-verbose:gc
-Xloggc:gc.log
-XX:+PrintGCTimeStamps
-XX:+PrintGCDetails
您可能遇到烫发空间限制,调整通过-XX:MaxPermSize=YYYm
无论如何,为了回答你的问题,我从没有最小值开始,并将最大值设置为相对较高。然后,我绘制gc日志的图形,找出我的稳定状态在哪里;直观地为各代选择高于平均水平的尺寸。像阅读财务图表一样阅读它,您会希望看到新一代的良好传播以及终身一代的持续增长和收集。如前所述,还要绘制您的烫发空间,以确保您不会不断增加。
GC调音是一门艺术,绝不是一门科学。