【问题标题】:Force the JVM to collect garbage early and reduce system memory used early强制 JVM 提前收集垃圾,减少系统内存使用
【发布时间】:2017-08-06 17:00:34
【问题描述】:

我们运行一个并非我们开发的 Java 应用程序。 此应用程序为某些任务使用相当多的内存,具体取决于所操作的数据,最高可达 4GB。在其他时候,只需要很少的内存,大约 300MB。

一旦 JVM 占用了大量内存,需要很长时间才能收集垃圾,甚至更长时间才能将内存返回给操作系统。这对我们来说是个问题。

发生的情况如下:JVM 需要大量内存来执行一项任务,并抓取 4GB 的 Ram 来创建一个 4GB 的堆。然后,处理完成后,内存只填充了 30%-50%。内存消耗变化需要很长时间。当我触发 GC(通过 jConsole)时,堆缩小到 500MB 以下。另一个触发的 GC 和堆缩小到 200MB。有时内存会返回给系统,但通常不会。

这是 VisualVM 的典型屏幕截图。堆被收集(使用的堆下降)但堆大小保持不变。只有当我通过“Perform GC”按钮触发 GC 时,堆大小才会减小。

我们如何调整 GC 以更早地收集内存? 性能和 GC-Pause-Times 对我们来说不是什么大问题。我们宁愿有更多更早的 GC 来及时减少内存。 我们如何调整 JVM 以将内存释放回操作系统,从而使 JVM 使用的内存更小?

我知道 -XX:MinHeapFreeRatio 和 -XX:MaxHeapFreeRatio,这有点帮助,但是用 VisualVM 观察堆告诉我们,它并不总是被遵守。我们将 MaxHeapFreeRatio 设置为 40%,然后在 VisualVM 中看到,堆仅填充到 10% 左右。

我们无法减少最大内存 (-Xmx),因为有时在短时间内确实需要大量内存。

我们不限于特定的 GC。所以任何能最好地解决问题的 GC 都可以应用。

我们使用 Oracle Hotspot JVM 1.8

【问题讨论】:

  • 也许可以试试[这个问题]。(stackoverflow.com/questions/12842863/…) 不过,不确定你所说的“还给记忆”是什么意思。
  • “Give memory back”是指将内存释放回给操作系统,这样更多的内存可以被其他应用使用,jvm使用的内存又要低了。
  • 明白了。我做了(不正确的)假设 GC 将内存释放回操作系统。
  • 所有可能的重复项都不能真正帮助完全解决问题。它确实有助于获得更早的 GC 以减少使用的堆。但是 JVM 并不会自行将内存释放回操作系统。它在外部(通过 Java VisualVM)或内部(通过 System.gc())显式触发 GC 时这样做。

标签: java memory memory-management garbage-collection jvm


【解决方案1】:

我假设您使用 HotSpot JVM。

然后您可以使用 JVM-Option -XX:InitiatingHeapOccupancyPercent=n (0

【讨论】:

  • 你知道吗,当堆的填充量超过提供的阈值时,会发生什么,但内存已全部使用且无法释放?这是否会导致重复收集,直到可以实际收集堆?
  • OP 没有说明他使用的是哪个收集器。 InitiatingHeapOccupancyPercent 仅适用于并发收集器,因此此建议可能没有用。
  • JVM 选项 -XX:InitiatingHeapOccupancyPercent=n 并不会真正降低内存消耗。它确实会导致更早的 GC 和更低的使用堆,但内存不会返回给操作系统。只有在外部(通过 Java VisualVM)或内部(通过 System.gc())显式触发 GC 时,内存才会返回给操作系统。
猜你喜欢
  • 2021-04-30
  • 2023-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-28
  • 1970-01-01
  • 2011-02-26
相关资源
最近更新 更多