Java堆不断缩小!这个堆大小图中发生了什么?

时间:2010-04-11 13:35:10

标签: java garbage-collection

这是运行ActiveMQ的JVM(win64,6u17)的屏幕截图,在每次垃圾收集后堆大小减少。随着堆大小的减少,垃圾收集变得更加频繁,并且堆减少得更快。最终,VM会锁定,因为它花费了所有时间在GC中。

-Xms 是默认值, -Xmx 是2048mb。

发生了什么事!!我怎么能避免这个?

http://imagebin.org/92614

Shrinking heap http://imagebin.org/index.php?mode=image&id=92614

n.b最初发布在serverfault.com上,按要求移至stackoverflow.com

3 个答案:

答案 0 :(得分:8)

Google从IBM JVM FAQ(如何获得NLA)中找到了以下内容:

  

Java堆何时收缩?

     

当GC确定存在大量可用堆存储时,会发生堆收缩,并且释放一些堆内存有利于系统性能。在GC之后发生堆收缩,但是当所有螺纹仍然悬挂时。

Sun JVM做了类似的事情。以下摘自Oracle技术网络文章Ergonomics in the 5.0 Java Virtual Machine

  

堆将增大或缩小到支持所选吞吐量目标的大小。在初始化期间和应用程序行为发生变化期间,可能会出现堆大小的一些振荡。

     

...

     

当垃圾收集器试图满足竞争目标时,堆的大小通常会振荡。即使应用程序已达到稳定状态,也是如此。实现吞吐量目标(可能需要更大的堆)的压力与目标竞争最大暂停时间和最小占用空间(两者都可能需要一小堆)。

我建议您查看该文档的其余部分;它可能有更多与您的问题相关的信息。

答案 1 :(得分:6)

有一个JVM参数控制何时调整堆的大小。

<强> -XX:MaxHeapFreeRatio

默认值为70.自由比率是堆上未分配的总空间大小的空间量。它可用空间的百分比超过70%的默认值,jvm会减小堆的大小,以允许操作系统使用内存。

如果堆经常缩小,则可以增加-XX:MaxHeapFreeRatio的值。如果设置为100,则可能永远不会溢出。

答案 2 :(得分:0)

猜猜: 看起来系统几乎空闲。可能会有一些缓存,并且东西从缓存中掉出来并获得gc'd。或者因为它是一个排队系统,也许它在队列中有一些消息,然后慢慢地被传递和gc'd。

gc-run的频率增加可能是由于系统负载不断减少。

至于如何避免它。你为什么要避免它?看起来您的CPU负载为零。所以你可以自由地让gc做任何想做的事情