许多 Java 虚拟机提供了选项来控制 Java 堆的大小和增长。本文讨论了如何正确设置最小值(ms)和最大值(mx)的堆大小。最小值参数是就是堆的起始大小,因此合理地设置它以及最大值参数,可能对您的 Java 应用会产生深远的影响。
mx 参数
在大多数情况下,如果您认为堆对于 Java 应用程序太小,就应该设置 mx 参数。通过在 Java 命令行上监视使用 verbosegc 参数运行的 JVM 的输出,您可以确定垃圾收集是否过于频繁。如果垃圾收集过于频繁,则请尝试增大堆的大小。
一般来说,如果应用程序不断出现内存不足错误,则我们建议您增大 mx 参数。这些错误可能是由于 Java 堆中可用空间不足而引起。
尽管设置堆大小没有规则可循,但下列原则可能会有所帮助:
不要使堆的增长超过系统的物理内存。换句话说,决不要将 mx 堆大小设置为大于 [(物理内存) - (操作系统和应用程序的工作区大小)]。另外,如果您运行多个 JVM,所有堆的大小总和应小于上述计算值。在 IBM Developer Kit for Windows,Java Technology Edition 中对堆增长有更好的支持
对于 Java 服务器应用程序,如果您发现没有达到最优性能,我们建议您检查堆的大小。IBM 通过智能地增大堆解决了这一普遍存在的 Java 问题。这种技术在 IBM Developer Kit for Windows,Java Technology Edition,1.1.7 版本中首次出现,并在 IBM Developer Kit for Windows and OS/2 Warp,Java Technology Edition,1.1.8 版本中得到增强。有了这些 JVM,用户几乎不需要设置堆大小;与智能增长搭配的初始默认值一般就足够了。
可能的负面影响
增大堆大小可以提高吞吐量,但会增加停顿时间。这是因为搜集大型的堆可能需要几秒钟的时间,但垃圾收集次数会减少。尽管这种偶然的响应时间变长对于直接通过 LAN 与服务器连接的客户机至关重要,但以响应时间的变长来换取吞吐量的增加是值得的。堆大小是一个体系结构问题,它取决于应用程序的用途。在 IBM Developer Kit for Windows and OS/2 Warp,Java Technology Edition,1.1.8 版本中,垃圾收集和堆增长的管理都是基于活动对象,因此停顿时间对性能的影响比在 1.1.7 版本中更小。
始终追求最好
查找最佳的堆大小可能需要对应用程序、 Java 实现和操作系统作一些试验。确定具体应用程序的最佳堆大小范围的一种方法是将 mx 设置得非常大,然后用 verbosegc 选项运行应用程序。这将产生有关堆使用情况的输出,您可以分析这个输出,以便对堆大小作出明智的决策。
另一种方法需要完成更多的工作,但它使系统维护更容易;这种方法就是确定服务器上的工作单元,即服务器完成工作的一个完整周期。例如,在批处理系统中,一个工作单元是一批请求。在更为典型的客户机/服务器信息检索周期中,工作单元可能是典型客户随其登录/退出序列一同提交的一系列请求。过程如下:
代码 System.gc() 调用工作单元 关闭异步垃圾收集和类垃圾收集(在命令行使用 -noasyncgc -noclassgc) 使用一个合成的驱动程序,使服务器反复执行此工作单元 采用电子表格分析 verbosegc 输出,以确定完成平均的工作单元所需的堆大小 将这个堆大小乘以工作单元数(例如,在指定时间内希望服务器处理的用户数或批处理数),并加上应用程序所需的基本堆大小,当然还有不很著名的"虚构因子"所生成的数字就是 mx 设置。这种方法需要完成更多的工作,但是,当服务器的实际负载改变时,堆大小随时可以调整。
ms 参数
ms 参数更为简单。如果您担心内存利用率和扩展的开销,则请将 ms 值设为 mx 的值。否则,就不要设置 ms。请注意,在 IBM Developer Kit for Windows and OS/2 Warp,Java Technology Edition,1.1.8 版本中,堆的大小既可以减小,也可以增大。因此,如果 ms 被设为某一值,堆则不能减小到该值以下。
我们的经验是最好的证明
一个客户最近所遇到的情况为我们提供了一个很好的例子,它说明 ms 和 mx 的不当设置可能导致哪些问题。该客户的系统是通过高速 SP 基架连接的一个多节点网络。每个节点包含 4 个 CPU,2 GB RAM。每个节点上运行 10 个 JVM。每个 JVM 都有其自己的设置,其中有个 JVM 将 ms 设为 32MB,将 mx 设为 256MB。
在启动后几分钟,系统停止运行,吞吐量几乎为零。在分析了 verbosegc 输出之后,我们调整了堆大小,将 ms 和 mx 设为 300MB。原来每个节点不能支持超过 20 个用户,这次更改后,现在可以轻松地支持 125 个用户。ms 很低的初始值会导致过多的垃圾收集和缓慢的堆增长,从而导致性能严重下降。
在所有情况下,全面了解与应用程序和所用 Java 环境的与堆相关的特征都非常重要。希望这个简短的讨论能够使您在处理您的 Java 应用程序时不会再遇到“堆问题”。
本文地址:http://com.8s8s.com/it/it18884.htm