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

原创 2001年05月04日 13:34:00

许多 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 被设为某一值,堆则不能减小到该值以下。

我们的经验是最好的证明
一个客户最近所遇到的情况为我们提供了一个很好的例子,它说明 msmx 的不当设置可能导致哪些问题。该客户的系统是通过高速 SP 基架连接的一个多节点网络。每个节点包含 4 个 CPU,2 GB RAM。每个节点上运行 10 个 JVM。每个 JVM 都有其自己的设置,其中有个 JVM 将 ms 设为 32MB,将 mx 设为 256MB。

在启动后几分钟,系统停止运行,吞吐量几乎为零。在分析了 verbosegc 输出之后,我们调整了堆大小,将 msmx 设为 300MB。原来每个节点不能支持超过 20 个用户,这次更改后,现在可以轻松地支持 125 个用户。ms 很低的初始值会导致过多的垃圾收集和缓慢的堆增长,从而导致性能严重下降。

在所有情况下,全面了解与应用程序和所用 Java 环境的与堆相关的特征都非常重要。希望这个简短的讨论能够使您在处理您的 Java 应用程序时不会再遇到“堆问题”。

大根堆小根堆及其应用

堆的概念 堆实际上是一棵完全二叉树,其任何一非叶节点满足性质: Key[i]=Key[2i+1]&&key>=key[2i+2] 即任何一非叶节点的关键字不大于或者不小于其左右孩子节点的关键字。 堆分...
  • IT_PCode
  • IT_PCode
  • 2014年03月25日 12:49
  • 4067

堆排序—大根堆,小根堆

1.小根堆 若根节点存在左子女则根节点的值小于左子女的值;若根节点存在右子女则根节点的值小于右子女的值。 2.大根堆 若根节点存在左子女则根节点的值大于左子女的值;若根节点存在右子女则根节点的值...
  • abcd1f2
  • abcd1f2
  • 2017年02月04日 15:27
  • 1100

堆的应用!--求第k大数

求一个数列中的第k大的数,将前k个数建最小堆,后面若比堆顶元素还小,则舍去,否则将堆顶置换成该元素,然后维护堆,最后输出堆顶元素~~ 若求第k小的数,则只需建最大堆即可。 #include int...
  • fengsigaoju
  • fengsigaoju
  • 2015年07月16日 19:48
  • 826

大根堆的插入、删除、修改优先级实现

大根堆其实就是一个一维数组, 不过数组中数据的排列是基于完全二叉树模型的。根节点的数据大于等于左孩子和右孩子节点的数据,然后每个子树都和前面一样。它的主要应用是在优先级队列中, 因为大根堆或小根堆总是...
  • haoyuedangkong_fei
  • haoyuedangkong_fei
  • 2016年05月26日 14:22
  • 1287

CPP(七):priority_queue的实现与大根堆的使用

实现的一个按int类型值大小从小打到
  • iamagoodguy254
  • iamagoodguy254
  • 2014年06月11日 13:26
  • 938

堆排序(大根堆)

堆排序是利用堆的性质进行的一种选择排序。下面先讨论一下堆。 1.堆   堆实际上是一棵完全二叉树,其任何一非叶节点满足性质:   Key[i]=Key[2i+1]&&key>=key[2i+2]...
  • chenhuajie123
  • chenhuajie123
  • 2013年09月22日 15:47
  • 17363

【算法导论之三】大根堆堆排序

1. 堆的概念(默认为二叉堆)     堆数据结构是一种数组对象,它可以被视为一棵完全二叉树。树中每个结点与数组中存放该结点的那个元素对应。树的每一层都是填满的,最后一层可能除外(最后一层从一个节点的...
  • houqingdong2012
  • houqingdong2012
  • 2013年05月07日 22:40
  • 1534

【数据结构-排序】大根堆的建立

粗略的写了一下大根堆的建立以及输出排序数据的过程,然后用图示来表示结果 程序如下: #include using namespace std; //节点声明,数据域、左孩子指针、右孩子指针 typed...
  • wodeai1625
  • wodeai1625
  • 2015年04月09日 21:43
  • 715

最大堆/最小堆【大根堆/小根堆】

堆的定义是:n个元素的序列{k1,k2,…,kn},当且仅当满足如下关系时被成为堆     (1)Ki 2i 且 ki 2i-1          或 (2) Ki >= k2i 且 ki...
  • a407603406
  • a407603406
  • 2014年10月23日 20:25
  • 1076

Java实现堆排序(大根堆)

堆排序是一种树形选择排序方法。设长度为n的一组数用堆来排序,首先用数组存储这组数。堆排序的特点是:在排序的过程中,array[0,…,n-1]可看成是一颗完全二叉树的顺序存储结构,利用完全二叉树中双亲...
  • lingang1991
  • lingang1991
  • 2017年04月04日 12:01
  • 493
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:错误的堆大小产生的 "堆问题"
举报原因:
原因补充:

(最多只允许输入30个字)