首页 > 解决方案 > Docker 容器中的 Java 内存设置

问题描述

我有一个基于 Java8 OpenJDK 的 Java 应用程序。它在一个限制为 20GB 的 docker 容器中运行。

tomcat的-Xms和-Xmx设置设置如下:

-Xms = 60% 的容器内存(由 cgroup 指定) - 所以 12GB -Xmx = 80% 的容器内存(由 cgroup 指定) - 所以 16GB

这会在容器上留下 4GB 可用空间,这通常很好,但有时在负载下我看到 docker 容器退出(并且 java 进程被杀死)并出现 OOM,因为容器内存使用量已超过 20GB。

我知道 -Xmx 设置是针对堆的,而不是针对整个 Java 进程和 JVM 的,因此希望容器上的 4GB“空间”就足够了,但似乎不是。

我知道所有用例都大相径庭,但我的问题是,一般而言,对于内存限制为 20GB 的容器,设置 -Xmx 设置是否太高。

我在玩弄使用 MaxRAM 设置的想法,我知道这只是决定堆内存,但我不确定这是否会产生积极的影响?

通常情况下您使用 MaxRAM 或 -Xmx,还是同时设置两者有什么好处?

如果我使用 MaxRAM 而不是 -Xmx,java 将如何为堆分配内存?是否有一个简单的算法来解决这个问题,例如 MaxRAM 设置的 50%?java会以这种方式更有效地管理内存吗?

标签: javadockermemoryjvm

解决方案


一般而言,对于内存限制为 20GB 的容器,设置 -Xmx 设置是否过高

这取决于。应用程序可以使用比指定更少的 RAM -Xmx,以及比指定多 2 倍或 3 倍的 RAM -Xmx。我见过很多这两种应用。

查看Java 进程中占用内存的内容

与其尝试根据给定的容器限制(这些限制可能完全不相关)来猜测适当的堆大小,不如将其设置-Xmx为对您的特定应用程序来说足够舒适的值?我的意思是,如果您的应用程序仅使用 8 GB 堆就可以正常工作,那么即使容器允许,也无需提供更多。

通常情况下您使用 MaxRAM 或 -Xmx,还是同时设置两者有什么好处?

设置两者是没有意义的,因为Xmxoverrides MaxRAM

我要使用 MaxRAM 而不是 -Xmx,java 将如何为堆分配内存?是否有一个简单的算法来解决这个问题,例如 MaxRAM 设置的 50%?

请参阅xmlx 和 MaxRAM JVM 参数有什么区别?

java会以这种方式更有效地管理内存吗?

MaxRAM,仅影响堆大小和默认垃圾收集器的计算(未明确指定时)。


推荐阅读