Docker - Java 容器不遵守内存限制

Docker - Java container doesn't respect memory limits

我已经阅读了多篇关于限制容器的 JVM 内存的帖子,到目前为止没有任何效果,我不知道我哪里搞砸了。

我在Spring Boot 中做了一个简单的"Hello World",使用REST 控制器,它没有别的。

此类应用程序导出为 WAR 文件,运行将其与 Tomcat JDK 11 图片结合使用,我也可以 运行 使用JDK 带有 FatJar 的图像,但问题仍然存在。


预计

让我的 Java 容器不占用超过 25 MB 的内存(为了数字,可以更多)

实际

如此简单的应用程序在 docker stats

中占用 200 - 250 MB 内存

Dockerfile

FROM tomcat:9.0.30-jdk11-corretto
COPY tomcat.war /usr/local/tomcat/webapps/ROOT.war
CMD ["catalina.sh","run"]

docker-compose.yml

version: '3.7'

services:
    hello:
        build:
            context: .
            dockerfile: Dockerfile
        image: app-test
        environment:
            - JVM_OPTS=-Xms13m -Xmx25m
        ports:
            - 8080:8080

我试过了

-Xms13m -Xmx25m

-XX:PermSize=13m -XX:MaxPermSize=25m

我已经删除并忘记的其他标志

tomcat 的 catalina.sh 脚本 java 选项所依赖的环境变量是:JAVA_OPTS。 如果您将撰写文件更改为使用以下环境变量,它应该可以工作。

environment: - JAVA_OPTS=-Xmx128m -Xms128m

除了 25m 对于具有 tomcat 运行.

的 JVM 来说似乎太小的内存这一事实

要限制 docker 容器的内存,您需要在 docker-compose.yml 文件中添加以下内容

environment:
  - <name>=<value>
deploy:
  resources:
    memory: 256M

添加上述代码后,容器将被限制在给定的内存限制内,您可以在 docker stats 输出中看到结果。有关资源限制的更多详细信息,请参阅 this docker 文档。

Note: If the container crosses the given memory limit, the kernel will kill the container.

无论您为 JVM 堆 (-Xmx) 设置多少内存,JVM 都会使用许多其他类型的非堆内存: - 您需要考虑到这一点。

您也可以完全避免设置 -Xmx,而是利用 -XX:MaxRAMPercentage: