【问题标题】:JVM release unused heapJVM释放未使用的堆
【发布时间】:2017-09-18 11:56:08
【问题描述】:

我有一个 Springboot 应用程序,Mule 在 docker 容器中作为微服务运行。即使它处于空闲状态,也需要大约 700MB。注意到 JVM 分配了 380 MB 的堆,这是使用-Xmx 参数提供的最大堆。虽然分配了最大堆,但微服务在空闲时仅使用大约 50 MB。问题是如何从 JVM 释放未使用的内存。

似乎减少 MaxHeapFreeRatio 我们可以要求 JVM 在有更多空闲内存比率时缩小。但是MinHeapFreeRatio=20 -XX:MaxHeapFreeRatio=40 并没有太大区别,JVM 也没有释放内存。但是当我使用带有上述两个参数的-Xmn 时,JVM 会按预期释放堆内存。示例场景见下图。

Java 版本 8

-Xmn100M  -XX:+PrintGCDetails  -XX:MinHeapFreeRatio=20 -XX:MaxHeapFreeRatio=40 -Xmx384M

  1. 为什么 MinHeapFreeRatio 和 MaxHeapFreeRatio 不能按预期工作?
  2. 如果上面的参数没问题,-Xmn 的结果是什么,它的值应该是多少?
  3. 还有哪些其他解决方案可以实现从 JVM 释放内存的任务?

【问题讨论】:

  • 这是一个非常有效的问题,我也分享。这不仅仅是“几 MB”。许多 Java 应用程序都有这样一种模式,在它们的生命周期中的某个时间,他们需要大量内存来完成一项可能是几 GB 的大工作,然后他们再也不会使用该内存量,因为内存永远不会释放到操作系统这是一个很大的浪费。

标签: java spring-boot jvm


【解决方案1】:

还有哪些其他解决方案可以实现从 JVM 释放内存的任务?

不确定您是否尝试过OpenJ9。它有一个调优机制来检测 JVM 何时空闲并将空闲内存返回页面释放给操作系统。这个article 谈论空闲调整功能。

您可以从adoptopenjdk 获取 OpenJDK-OpenJ9 二进制文件。

如果您坚持使用 OpenJDK-Hotspot 组合,您可以尝试探索 –XX:-ShrinkHeapInSteps 选项,该选项有望大幅缩小堆,但我不确定它适用于哪些 GC 策略。

【讨论】:

    【解决方案2】:

    首先,这应该真的是评论,但它可能会变得很大。如果您真的想将内存从 JVM 释放回操作系统,请问问自己。重新获取它会很昂贵,就像运行您的应用程序那样可能更昂贵 - 它会减慢您的速度。

    那么,您在 java-8 下的默认收集器是 Parallel GC,我不太非常确定那些 MinHeapFreeRatioMaxHeapFreeRatio 是否真的可以使用它。我尝试过使用G1GC - 确实如此,但没有使用Parallel。然后添加-Xmn 可能只是运气/好时机; AFAIK 它不应该影响其他两个参数。 this 是您遇到的类似问题的一个相当有趣的答案。

    【讨论】:

      猜你喜欢
      • 2016-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-12
      • 1970-01-01
      • 2018-06-01
      • 2017-07-06
      • 2011-05-06
      相关资源
      最近更新 更多