当前位置: 首页 > 图灵资讯 > 技术篇> 错误的堆大小产生的 "堆问题"

错误的堆大小产生的 "堆问题"

来源:图灵教育
时间:2024-02-25 14:02:47

许多 Java 虚拟机提供控制虚拟机选项的选项 Java 堆的大小和增长。本文讨论了如何正确设置最小值(ms)和最大值(mx)堆的大小。最小值参数是堆的起始大小,因此合理设置和最大值参数可能对您有利 Java 应用程序会产生深远的影响。

mx 参数 在大多数情况下,如果你认为堆对 Java 如果应用程序太小,应该设置它 mx 参数。通过在 Java 命令行上监控使用 verbosegc 参数运行的 JVM 您可以确定垃圾收集是否过于频繁。如果垃圾收集过于频繁,请尝试增加大量。

一般而言,如果应用程序不断出现内存不足的错误,我们建议您增加内存 mx 参数。这些错误可能是由于 Java 由于堆中可用空间不足造成。

虽然没有规则可以遵循设置堆的大小,但以下原则可能有所帮助:

不要使堆的生长超过系统的物理内存。换句话说,千万不要将就 mx 堆大小设置为大于 [(物理内存) - (操作系统和应用程序的工作区域大小)。另外,如果你操作多个, JVM,所有堆的总大小应小于上述计算值。 若应用程序所需的堆超过总物理内存的一半,则请设置 mx 参数。在 IBM Developer Kit for Windows,Java Technology Edition, 版本 1.1.8 中,mx 参数的默认值是总物理内存大小的一半。 如果你的应用程序经常依赖终止函数 (finalizer) 需要减少的操作 mx 设定的大小。(注:我们建议您避免这种代码设计。)

在 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 应用程序不会再遇到“堆问题”。