这是运行ActiveMQ的JVM(win64,6u17)的屏幕截图,在每次垃圾收集后堆大小减少。随着堆大小的减少,垃圾收集变得更加频繁,并且堆减少得更快。最终,VM会锁定,因为它花费了所有时间在GC中。
-Xms 是默认值, -Xmx 是2048mb。
发生了什么事!!我怎么能避免这个?
Shrinking heap http://imagebin.org/index.php?mode=image&id=92614
n.b最初发布在serverfault.com上,按要求移至stackoverflow.com
答案 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做任何想做的事情