Java 17 应用程序在 docker 中显示 RAM 使用率非常高

标签 java docker garbage-collection

我有一个应用程序,在空闲时间通常只需要 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/

相关文章:

java - Camel - unmarshal().serialization() - ClassNotFoundException

java - 在当前类型是抽象对象的具体对象上调用具体方法

Docker 查看历史日志

docker - Docker 命令的含义

java - 如何监控垃圾回收以查看哪些内容被GC了?

java - 高 Perm Generation 和低 Old Generation

java - 有没有办法在 Java 代码运行时更改 TextView 中的文本?

java - GWT:重新加载 Web 服务器不工作

unix - 如何将命令行选项传递给我的 dockerized GoLang 程序?

python - __del__() 如何干扰垃圾回收?