为什么 运行 垃圾收集器有时会增加保留的 ram java?

why running garbage collector sometimes increase reserved ram java?

我们在 tomcat8.5.47 上有一个 java8 网络应用程序 运行 server.we 每次只有 20-60 个用户会话,但大部分时间高达 600mb在 server.we 上上传文件也使用 hibernate 和 c3p0 来管理数据库连接。 我们监控服务器好几天,发现有时 java 保留内存突然增加,垃圾收集器没有释放 it.how 我们能解决这个问题吗?有什么方法可以释放保留内存并防止 tomcat增加内存?还有什么方法可以减少任务管理器中使用的内存?

这些是我们的设置:

-XX:MaxPermSize=1g  -XX:+UseG1GC  -XX:+UseStringDeduplication  -XX:MaxHeapFreeRatio=15  -XX:MinHeapFreeRatio=5  -XX:-UseGCOverheadLimit  -Xmn1g  -XX:+UseCompressedOops  -Xms10g  -Xmx56g

这是发生这种情况时分析器的图像:

这是 2 小时后分析器和任务管理器的图像:

P.s。我们使用 jprofiler 进行分析,绿色显示保留的 ram,蓝色用于在第二个框中使用 ram.also,您可以跟踪 gc activity,第三个用于 类,第四个显示线程活动最后是 cpu 活动。
谢谢大家的回答。

Java8 不会 return 将 RAM 分配回 OS 即使 JVM 不需要它。对于该功能,您需要移动到另一个版本的 JDK。这是 https://openjdk.java.net/jeps/346 的 JEP,它说它是在版本 12 中交付的,所以我假设 JDK 12 之后的版本应该具有该功能。 防止增加保留内存的唯一方法是减小 Xmx 值。并且由于您将其设置为 56g,我假设您可以接受 Tomcat 消耗多达 56g 的内存。所以如果你认为它太多了,那么就减少那个数字。

这类问题绝非易事,主要是因为要“正确”回答问题,提问者需要对 OS 如何对待和处理记忆有一些基本了解;以及内存有 种不同的 类型这一事实(至少 residentcommittedreserved)。到目前为止,我还不够多才多艺,无法完全正确地做到这一点,但我一直在学习并在这方面做得更好。它们的意思非常不同,其中一些通常是无关紧要的(我发现 reserved 是这样)。您正在使用 windows,因此 this, imho 是必看的开始。

看完之后,您需要转到 JVM 世界以及 JVM 进程。堆由垃圾收集器管理,因此要 收缩 一些 un-used 堆 - GC 需要能够做到这一点。同时,before jdk-12, G1 could do that - it was never very eager to. Since jdk-12, there is this JEP 将 return 记忆恢复,即:它将 un-commit 记忆恢复。不过,请务必在发生这种情况时阅读。另请注意,其他 收藏家如 Shenandoah and/or ZGC 更经常这样做。

当然,由于您禁用 -UseGCOverheadLimit,您会在 CPU 中获得巨大的峰值(GC 线程 运行 疯狂地释放 space)当然一切都变慢了。如果我是你,我会启用那个,让 GC 失败并分析 GC 日志以了解发生了什么。 56GB 的 Heap 对于 20-60 个用户来说是一个巨大的数字(这看起来肯定是泄漏?)。请注意,如果没有 GC 日志,这可能无法解决。

P.S。查看您共享的第一个屏幕,注意那里有两种颜色:绿色和蓝色。我不知道那是什么工具,但看起来绿色是“保留内存”,蓝色是“已使用”(this is what used means)。但如果你能准确地说出这些是什么就太好了。