【问题标题】:Why does this java process not release memory?为什么这个java进程不释放内存?
【发布时间】:2016-11-06 12:46:31
【问题描述】:

我编写了一个 java 应用程序,并在 Fedora 24 下运行了 java 进程。然后我检查了 jconsole,发现它使用了大约 5 到 10 兆字节的内存。 垃圾回收的效果在图中也可见。

截图如下:

然后我检查了我的系统监视器,发现同一个进程 ID 的内存使用量超过 100 兆。

截图如下:

请告诉我为什么进程不释放未使用的内存?

有什么办法可以释放吗?

【问题讨论】:

  • 这是什么java应用程序?摇摆?
  • @CoderinoJavarino 没有。这些名字在他们的标题和我的文字中可见。
  • 你为什么在乎?这适用于 Intellij,一个非常大的基于 Java 的程序。您并没有抱怨 Chrome 在至少显示的两个进程中占用了超过 100MB 的空间。 100MB 并不是非常多的内存——你的 Gnome 进程会占用更多的内存。如果您真的有问题,请告诉我们。 100MB 的内存已经不算什么了。
  • @stdunbar 我很在意,因为我在 Mono 和 .NET 中没有遇到过这种问题。我知道 100 MB 不算什么,但我问这个问题是为了提高我的知识,而不是因为遇到问题。
  • 您正在查看 IntelliJ 的内存 - 而不是您的进程本身。使用 Java 命令在命令行上运行程序,因为很难从 IntelliJ 中分离出您的进程及其内存消耗。

标签: java memory memory-management heap-memory


【解决方案1】:

used heap 和 allocated heap 是有区别的。图表中的蓝线是已用堆 - 堆中实际保存了多少对象。未显示的是分配的堆的大小 - 这更大,通常更大,因此 JVM 可以分配更多对象而不会耗尽空间并且必须返回操作系统以获得更多内存(这很昂贵)。在您的情况下,系统显示的 100mb 中的一部分是 JVM 本身,但其中大部分可能已分配但未使用的堆。

当你运行一个 Java 程序而不指定你希望它使用的堆大小时,JVM 会尝试根据你的机器、操作系统、JVM 版本等找出一个合理的设置。当我在我的计算机上运行一个简单的 Hello World 时具有 16GB RAM 和 Java 8 的机器最初为堆分配了 256mb。显然比它需要的要多得多!如果我想强制它使用更少,我可以使用-Xms 命令行设置初始堆分配,-Xmx 设置允许的最大值。我的猜测是,如果您设置类似-Xms20m 的内容,您会看到进程使用的内存更少。在 IntelliJ 中,将该设置添加到运行配置中的 VM Options 字段。

【讨论】:

    【解决方案2】:

    系统监视器中报告的内存是进程使用的所有内存,而不仅仅是 Java 堆。这段记忆包括:

    • VM 本身的可执行文件,以及它已加载的库
    • VM 的工作空间作为一个进程,用于 Hotspot 编译器、GC、IO 缓冲区、屏幕和图形缓冲区、读取 VM 文件等
    • Java 堆和其他可报告的内存结构

    在您的情况下,10MB 的进程用于存储 Java 堆栈和 Java 对象。另外 90MB 是 Java 程序本身和 VM 内部的内存。

    这是一个简短的答案,但还有一个重要的考虑因素 - Java 可以(并且确实)将多余的堆释放回操作系统。这由-XX:MinHeapFreeRatio-XX:MaxHeapFreeRatio 标志控制。默认情况下,MaxHeapFreeRatio 为 70% - 这几乎与堆图中显示的完全一样(从 6MB 到略低于 10MB 的锯齿模式)。如果您的应用有明显较大的下降,您会在系统监视器中看到 Java 进程的(小)锯齿状图案。

    为了提高性能,您通常应该允许 JVM 保留从 GC 中释放的大量堆。为什么?因为我们知道 JVM 将立即需要重新开始分配内存,而 Java 的进程(和操作系统)保持这一点会更有效率。

    所以,总结一下:

    • 系统监视器显示整个 JVM 进程使用的内存
    • Java 堆只是进程中使用内存的项目之一
    • 在 GC 之后,JVM 持有(至少一部分)它释放的堆(通常)性能更高,因为我们几乎肯定会在接下来的几秒钟内使用它
    • 本例中的 Java 堆在正常范围内振荡,本例中的默认内存配置允许 Java 在 GC 后保留所有多余的堆

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-08-02
      • 2013-01-12
      • 2014-12-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多