Jenkins Docker容器未使用传入的JAVA_OPTS配置的内存分配,求助排查原因
各位大佬好,我最近碰到个棘手的问题,想请大家帮忙分析下:
我在Amazon Linux上用Docker 25.0.13部署Jenkins容器,启动脚本是这么写的:
JENKINS_HOME=/home/jenkins JENKINS_VERSION=2.528.3 docker run --restart=unless-stopped -d -p 8080:8080 -v $JENKINS_HOME:/var/jenkins_home --name jenkins_master --env JAVA_OPTS="-Xms24g -Xmx24g" jenkins_master:$JENKINS_VERSION
容器启动后,我进容器查环境变量是对的:
docker exec -u 0 -it jenkins_master bash root@7fa1cec2299c:/# echo $JAVA_OPTS -Xms24g -Xmx24g
但宿主机用free -g看内存,发现容器只占了2G左右,而另一台配置完全一样的EC2实例上,同款Jenkins容器能用到20G内存(那台跑了不少构建任务)。当前实例的内存情况:
total used free shared buff/cache available Mem: 31 2 25 0 2 27 Swap: 77 0 77
用htop确认过,确实只跑了2G内存。我明明给JVM配了24G堆内存,为啥没生效呢?求各位给点排查思路!
我自己先捋了几个可能的排查方向,也欢迎大家补充:
先确认Java进程实际有没有加载配置
进容器执行ps aux | grep java,看看Java进程的启动参数里有没有-Xms24g -Xmx24g。毕竟环境变量对了,不代表启动命令里真的用了它。
另外也可以看Jenkins日志:cat /var/log/jenkins/jenkins.log | grep -i "heap\|xmx",正常日志里会输出JVM堆内存配置,比如Picked up JAVA_OPTS: -Xms24g -Xmx24g或者Max heap size: 25165824.0 MB这类内容。检查自定义镜像的启动脚本
因为用的是自己构建的jenkins_master:$JENKINS_VERSION镜像,得确认Dockerfile里的ENTRYPOINT/CMD有没有正确引用$JAVA_OPTS。比如如果启动命令是java -jar /usr/share/jenkins/jenkins.war,那肯定不会加载环境变量里的配置,得改成java $JAVA_OPTS -jar /usr/share/jenkins/jenkins.war才行。Jenkins还没达到内存使用阈值
要是你的Jenkins还没跑任何构建任务,或者任务都很轻量,JVM堆内存是按需分配的,不会一开始就占满24G。可以登录Jenkins WebUI,进「系统管理」→「系统信息」,找「JVM Arguments」和「Heap Memory Usage」:- 如果这里显示Max Heap是24G,但当前只用了2G,那就是正常的,跑几个内存密集的构建任务后,内存使用自然会上去;
- 如果这里Max Heap还是默认值(比如2G),那就是配置确实没生效,得回到前两步找原因。
检查Docker的容器内存限制
虽然Docker默认不限制容器内存,但也可以确认下:执行docker inspect jenkins_master | grep -A 10 "Memory",看看Memory和MemorySwap是不是0(0代表无限制)。如果Memory是2147483648(也就是2G),那就是Docker本身把容器内存限死了,JVM再怎么配置也没用。JVM参数的兼容性问题
要是镜像用的是老版本JDK,可能有些默认行为会影响堆内存分配。可以进容器执行java $JAVA_OPTS -XX:+PrintFlagsFinal | grep HeapSize,看看实际的MaxHeapSize是不是24G。如果输出里的MaxHeapSize还是很小,那可能是JDK版本的问题,或者有其他参数覆盖了-Xmx。
如果大家有遇到过类似的问题,或者有其他排查思路,麻烦留言告诉我,谢谢啦!




