我有一个应用程序,在空闲时间通常只需要 1GB RAM,但是当我在 docker 中启动它时,它会从外部显示更高的 RAM 使用量(5GB)。 JVM 指标显示我仍然只使用 ~1GB 的 RAM,但 JVM 并没有真正释放它所占用的任何 RAM。 我无法减少 RAM 限制(使用 MaxRamPercentage 时约为 8GB),因为它在高负载、启动和一些特殊事件期间需要它。我可以定期调用 System.gc(),因为这会释放大量内存,但 RAM 在几次请求后会恢复到原来的状态。这种对未使用 RAM 的声明会浪费大量资源,并导致服务器出现 OOM,因为没有应用程序释放其内存。
根据这个JEP-346 “错误”已被修复,该错误导致垃圾收集器无法释放内存,但我没有看到任何改进。
出于测试目的,我还尝试使用 -XX:+UseShenandoahGC
并且它按预期释放了内存。但在启动过程中,它会占用几乎所有 RAM,这会导致服务器/多个同时应用程序重新启动期间出现问题。
TLDR:实际使用 RAM ~1 GB,声称 RAM ~5 GB,RAM 限制 ~8GB。 如果没有显式调用 System.gc(),默认 GC 不会释放足够的 RAM。 G1 GC 是 Java 17 中的默认 GC 吗? (AFAICT 是) 从 JEP-346 进行更改是否需要任何参数按预期工作吗?
最佳答案
我认为this is similar question to what you are asking .
正如问题评论中指出的那样,此功能是可选的,可以使用 JEP 346 Documentation 中描述的参数启用。 .
-XX:G1PeriodicGCInterval
和 -XX:G1PeriodicGCSystemLoadThreshold
都必须设置为大于默认值 0 的值才能使该功能正常工作。
关于Java 17 应用程序在 docker 中显示 RAM 使用率非常高,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70147299/