为什么调用 System.gc() 会导致内存使用量显著降低?

Why does invoking System.gc() lead to a significant decrease in memory usage?

提问人:Yunus Emre Guney Student 提问时间:11/7/2023 最后编辑:Yunus Emre Guney Student 更新时间:11/7/2023 访问量:81

问:

我有一个长时间运行的 JVM Spring 服务器应用程序,它经历了连续处理。我注意到随着时间的推移,内存使用量逐渐增加,但它从不会导致 JVM 内存不足崩溃。但是,当我手动生成堆转储时,我观察到内存使用量显著下降,恢复到最初的预期水平。当我分析转储时,我没有看到任何异常,因为转储可能是用垃圾收集内存生成的。据我所知,发生这种下降是因为生成堆转储会触发垃圾回收器工作。

为了测试此行为,我尝试调用 System.gc(),它重现了内存丢弃。我很好奇为什么会这样。为什么 JVM 不会自动执行此垃圾回收?似乎,出于某种原因,如果没有我明确强制清除它,它就不会这样做。但正如我所提到的,这不会导致JVM崩溃。它可能会在需要时释放该内存。这是在 Kubernetes 上运行的自动缩放应用程序,由于内存增加,此行为会导致不必要地创建其他实例。

是否有可以传递给JVM的与此行为相关的参数?

我希望JVM自动清除内存,而无需我显式调用System.gc()

Java Spring 管理内存 泄漏 JVM

评论

1赞 M. Deinum 11/7/2023
有一种关于何时触发 gc 的算法,显然这些限制并没有使 JVM 认为需要 GC。
0赞 John Bollinger 11/7/2023
您如何衡量内存使用情况?
0赞 Yunus Emre Guney Student 11/7/2023
@JohnBollinger我使用 (((UnixOperatingSystemMXBean) osBean).getTotalPhysicalMemorySize());然后我使用 (UnixOperatingSystemMXBean) osBean).getFreePhysicalMemorySize();我检查两者之间的差异并计算使用中的内存
0赞 Yunus Emre Guney Student 11/7/2023
@M.Deinum,我能做些什么来改变这种行为吗?
1赞 John Bollinger 11/7/2023
@YunusEmreGuneyStudent,你不是在衡量你认为你在衡量的东西。这里至少有三个混杂因素:(i) 系统上运行的其他进程会导致内存负载;(ii) 您只查看物理内存,而忽略了虚拟内存;但最重要的是 (iii) 归因于 Java VM 的内存量与活动对象占用的空间量不同。进程在释放内存时不一定会将其返回给操作系统。通常,可用内存仍分配给进程。

答:

2赞 John Bollinger 11/7/2023 #1

为什么 JVM 不会自动执行此垃圾回收?

Java 会自行决定自动运行垃圾回收器。这样做的时机和效果取决于许多因素,并非所有 GC 运行都是相同的。除其他事项外,收集无法访问的对象可为 VM 提供更多内存,但从操作系统的角度来看,这并不一定会减少 VM 的内存使用量。

从操作系统的角度来看,手动请求 GC 也不一定能减少 VM 的内存使用量。事实上,它的文档没有做出任何具体的承诺,并明确否认了其中的几个:System.gc()

当控制从方法调用返回时,Java 虚拟机 已尽最大努力从所有未使用的对象中回收空间。那里 并不能保证此努力将回收任何特定数量的 未使用的对象,回收任何特定数量的空间,或完成 任何特定时间,如果有的话,在方法返回之前或永远。 也不能保证这种努力将决定变化 在任何特定数量的对象中的可达性,或者任何 特定数量的对象将被清除并排队。Reference

你接着说,

这是一个在 Kubernetes 上运行的自动缩放应用程序,而这个 行为会导致不必要地创建其他实例 由于内存增加。

有没有我可以传递给的参数 JVM 与此行为相关?

这是特定 VM 的一项功能。没有与问题相关的标准 VM 选项,但您的特定 VM 可能具有影响 GC 策略和计时的选项,也可能有一些选项会影响 VM 将使用的内存总量。有关详细信息,应查看 VM 的文档。

如果您碰巧使用的是 Oracle / OpenJDK VM,那么 Oracle 关于 GC 调优的相当广泛的文档将对您感兴趣。选择适用于特定 VM 版本的文档版本。例如,如果您使用的是 Java 21,那么您正在寻找 https://docs.oracle.com/en/java/javase/21/gctuning/introduction-garbage-collection-tuning.html#GUID-326EB4CF-8C8C-4267-8355-21AB04F0D304