代码之家  ›  专栏  ›  技术社区  ›  PeterMmm

堆内存行为

  •  6
  • PeterMmm  · 技术社区  · 15 年前

    我总是对堆内存行为有疑问。

    分析我的应用程序我得到上面的图表。看起来一切都很好。但我不明白的是,为什么在GC时,堆会变小,即使有足够的内存(红色圆圈)。

    这意味着对于一个长时间运行的应用程序,它将在某个时候耗尽堆空间?

    alt text

    2 回复  |  直到 15 年前
        1
  •  6
  •   Andrzej Doyle    15 年前

    不一定。垃圾回收器可以以任何它认为合适的方式使用最大的已分配堆。基于当前行为(但具有不同的存储条件)推断未来的GC行为并不能保证是准确的。

    这确实有一个不幸的副作用,即很难确定OutOfMemoryError是否 除非发生。一个合法的(但可能效率很低)垃圾收集器在内存上限被击中之前什么也做不了,然后做一个停止世界标记并扫描整个堆。在这个实现中,您会看到自己的内存不断增加,并且可能会忍不住说OOME即将到来,但是 你就是说不出来 .

    对于这么小的堆大小,这里的增加可能只是由于簿记/缓存大小对齐等原因。您所说的小于50KB左右的分辨率,所以我不必担心。

    如果你 认为OutOfMemoryErrors存在合法的风险,唯一的方法是将压力测试放在一起,并显示应用程序确实耗尽了堆空间。

        2
  •  4
  •   Stephen C    15 年前

    查看内存图,您将看到堆大小的增加发生在“saw points”;即本地最大值。每一个都对应于运行一个完整的GC。如果仔细观察堆被扩展的“点”,您会发现在每种情况下,紧跟在完整GC之后的可用空间量都比前面的“点”要高一些。

    (另一种可能是应用程序内存泄漏缓慢。)

    这意味着对于一个长时间运行的应用程序,它将在某个时候耗尽堆空间?

    不。假设应用程序的内存使用量(即可访问对象占用的空间的整数)是循环的,堆大小将接近固定的上限,并且永远不会超过它。当然,OOME并不是不可避免的。