如何设置Docker容器中Java应用的内存

Dokcer 容器如何限制内存

我们知道docker使用Linux内核的 CGroup 来实现限制容器的资源使用(CPU,内存), 然而 CGroup 功能是到2007年才加入 Linux2.6.24 内核的,一些可以从运行时环境收集信息的应用程序再 CGroup 之前就已经存在了。所以在容器中执行 top free ps 等一些命令其实是显示了容器所在宿主机上的信息。

容器的资源限制可以在 docker run 中通过配置来实现,但是这依赖系统内核的支持,可以通过 docker info 来查看,如果有一下输出:

WARNING: No swap limit support

那就请查看你系统的相关文档来开启。

Memory 资源

在 Linux 系统中,系统内核为了保障系统运行,但系统中剩余的内存不足以维持系统的正常运行,系统内核就会根据 OOM priority 来 kill 掉进程以释放内存,这就会引发 OOME 或 Out of Memory Exception 错误。Docker 会尝试着调整 Docker daemon 的 OOM priority 来尽可能地避免被内核 kill 掉,但是容器的进程就没有这个能力了。

Option Description
-m, --memory="" 内存限制,格式是数字加单位,单位可以为 b,k,m,g。最小为 4M
--memory-swap="" 容器的内存能 swap 到硬盘的大小,只有在设置了 -m 的情况下,才有意义; 这个值的大小= memory + swap,更多详情请见下方。
--memory-reservation 内存的软性限制。格式同上
--oom-kill-disable 是否阻止 OOM killer 杀死容器,默认不阻止。
--oom-score-adj 容器被 OOM killer 杀死的优先级,范围是[-1000, 1000],默认为 0
--memory-swappiness 用于设置容器的虚拟内存控制行为。值为 0~100 之间的整数
--kernel-memory 核心内存限制。格式同上,最小为 4M

--memory-swap 配置详情:

--memory-swap 设置的前提是要先设置了 --memeory, 一下的讨论均是假设于设置了有效的 memory,而且宿主机的内核必须开启了支持 swap limit 的设置;

  • 如果 --memory-swap 为 0 或者不设置,swap = 2 * memory 的大小。比如,docker rum -m 2G 设置了一个容器最大允许使用的内存是 2G,那么 swap 最大能使用的大小为 4G。
  • 如果 --memory-swap 为 1, 则不允许容器使用 swap。

Docker容器中Java应用的内存如何分配

Docker Java 应用的内存应该是 JVM 的 Heaper内存 + Metaspace的内存。

默认在没有通过 JAVA_OPTS 指定 JVM maximum heap size 的情况下,它默认为操作系统内存的1/4。

自从docker 1.7版本之后,Docker 把容器的 local cgroup 以只读的方式挂在到容器的内部文件系统上,这样我们可以在容器内部读取这个限制的值, 我们可以通过修改容器的启动脚本来实现自动计算:

#!/bin/bash

# local cgroup
limit_in_bytes=$(cat /sys/fs/cgroup/memory/memory.limit_in_bytes)

limit_in_megabytes=$(expr $limit_in_bytes \/ 1048576)

heap_size=$(expr $limit_in_megabytes - $RESERVED_MEGABYTES)

JAVA_OPTS="-Xmx${heap_size}m $JAVA_OPTS"

java $JAVA_OPTS -jar xxx.jar
  • 另外, 从 Java9 开始, 在没有通过 JAVA_OPTS 指定 JVM maximum heap size 的情况下,默认为容器启动时指定的 --memory 1/4 的大小。详情见:https://blogs.oracle.com/java-platform-group/java-se-support-for-docker-cpu-and-memory-limits

参考

  • https://docs.docker.com/config/containers/resource_constraints/#memory

你可能感兴趣的:(如何设置Docker容器中Java应用的内存)