与使用的百分比相比,堆大小意外地大了

与使用的百分比相比,堆大小意外地大了

问题描述:

有内存分配问题我希望得到您的帮助。我们已经分析了一些顶级的服务,我们注意到它们的RES值约为1.8GB,据我了解,这意味着他们当时只能保持1.8GB的内存。如果我们刚刚开始它们(它们实质上是从缓存中读取数据,处理数据并推送到另一个缓存),但是看到我们在CPU密集型处理完成后仍然可以看到这一点,我们就会好奇它是否会意味着某些事情没有按照我们的预期进行GC'ed。与使用的百分比相比,堆大小意外地大了

我们用下面的参数运行程序:-Xms256m -Xmx3096m这我理解是指256的初始堆大小,和3096

最大堆大小现在我倒是希望看到堆是根据需要最初增长的,然后根据需要收缩,因为内存被释放(尽管这可能是我的第一个错误)。我们实际上看到jvisualvm是:使用的堆为1GB,堆 的大小为2GB

  • 5分钟的:我们已经做了处理,所以 使用的堆急剧下降到

    • 3分钟邻近 足够齐尔希,堆大小但只有 滴至约1.5GB
    • 7分钟 - >:实时小比特 处理周期性地,仅使用100-200MB左右之间曾经堆 , 堆大小但是保持恒定 约1.7GB。

    我的问题是,为什么我的堆没有缩小,因为我可能预期它?这不是盗取了有价值内存的Linux盒子上的其他进程,如果是的话,我该如何解决它?我们确实有时会发现内存不足的错误,并且这些进程被分配了最“意外”的内存大小,我认为最好从它们开始。

    干杯, 戴夫。

    (〜请原谅可能缺乏对JVM内存优化谅解!)

  • +0

    也许分配一些更多的交换。由于许多这些页面未被使用,它们可以被内核分页而不会造成垃圾。对于常驻记忆,其他过程应该很好。 – wds 2011-03-25 10:50:56

    你可能想看看this answer关于调整堆扩展和收缩。默认情况下,JVM对于缩小堆不太积极。此外,如果堆有足够的可用空间很长一段时间,它不会触发GC,我相信是唯一的时间被认为是缩小它。

    理想情况下,您可以将最大值配置为在满负载情况下为应用程序提供足够空间的值,但如果操作系统始终都处于使用状态,则可以接受操作系统性能。为了可预测性和潜在的更好性能,将最小值设置为最大值并不罕见(我没有任何可供参考的参考)。

    +0

    谢谢WhiteFang。我想,时间可以看看更积极的堆缩减。 – f1dave 2011-03-25 09:47:04

    +0

    我想知道的另一件事是这样的事情依赖于操作系统? Linux会以不同的方式处理内存/堆问题,比如Windows等等? – f1dave 2011-03-25 09:49:55

    +0

    大多数情况下,我相信操作系统对内存/堆栈调整无关紧要。我确信在说明操作系统细节方面有一些细微的差异,但是JVM通常设计的行为相同。 Solaris往往有一些额外的旋钮,但我怀疑它会有多大帮助。 – WhiteFang34 2011-03-25 09:56:17

    我没有一个完整的答案,但a similar question has come up before。从之前的讨论中,您应该调查-XX:MaxHeapFreeRatio=作为您的调整参数,以强制堆释放回操作系统。有documentation here,我相信默认值允许非常大量的未使用的堆仍由JVM拥有。

    那么,GC并不总是运行时,你认为它并不总是收集什么是合格的。如果它几乎用完了堆空间,那么它可能只会开始从旧的gen空间收集对象(因为从旧gen收集通常会涉及GC试图避免的停止世界收集,直到它真的需要做它)。

    也许你可以尝试使用TPTP,visualvm或JProbe(商业版,但试用版)进行分析,找出发生了什么。

    另一件需要注意的是文件处理程序;我没有详细信息,但是我的一位同事在几年前遇到了由打开许多文件的进程导致的堆饱和问题,并且发现每次他打开一个4kb的缓冲区时,都会分配到本地堆中,在处理结束时释放。我希望这个相当模糊的迹象可能会有所帮助...

    +0

    谢谢zim - 但我已经用visualvm来查看它,这是我如何得到原始问题中的数字。 – f1dave 2011-03-25 10:38:54