Debian10服务器OOM异常:配置SWAP未被使用问题求助
问题分析与解决
服务器环境
- Debian 10系统,物理内存16GB
- 运行3个Docker容器:NGINX、PostgreSQL数据库、Keycloak认证服务
- 运行2个Java金融计算程序,启动命令如下:
./java/jdk/bin/java -Xmx10g -jar portal-backend-1.0-SNAPSHOT-runner.jar 2>&1 >> log/portal.log & ./java/jdk/bin/java -Xmx10g -jar pea-backend-1.0-SNAPSHOT-runner.jar 2>&1 >> log/pea.log &
SWAP配置情况
已配置24GB SWAP文件,操作步骤:
- 创建并设置权限:
fallocate -l 24G /swapfile chown root:root /swapfile sudo chmod 0600 /swapfile
- 格式化并激活:
mkswap /swapfile swapon /swapfile
- 写入
/etc/fstab实现开机自动挂载:
/swapfile swap swap defaults 0 0
执行swapon -s查看状态,SWAP使用率始终为0:
Filename Type Size Used Priority /swapfile file 25165820 0 -2
核心问题
已激活SWAP文件,但仍频繁出现out-of-memory exception,且SWAP文件始终未被使用(使用率为0)。
OOM触发前的资源状态

问题根源
- Java堆内存配置过载:两个Java程序各设置
-Xmx10g,合计最大堆内存需求达20GB,直接超过服务器16GB物理内存。Linux的OOM Killer会在内存耗尽前直接终止进程,系统根本来不及调度使用SWAP。 - SWAP优先级与系统调度阈值不匹配:当前SWAP优先级为
-2(较低优先级),且Debian 10默认vm.swappiness值(控制物理内存使用到多少比例才触发SWAP)通常为60。Java进程快速占满物理内存的情况下,系统还没触发SWAP调度就已经触发OOM。 - 容器内存占用未预留:NGINX、PostgreSQL、Keycloak三个容器本身也会占用物理内存,进一步压缩了Java程序的可用内存空间,加速OOM触发。
解决方案
- 调整Java堆内存参数:
降低单个Java程序的最大堆内存,比如调整为-Xmx6g,两个程序合计12GB,预留3-4GB物理内存给系统和容器使用。示例命令:./java/jdk/bin/java -Xmx6g -jar portal-backend-1.0-SNAPSHOT-runner.jar 2>&1 >> log/portal.log & ./java/jdk/bin/java -Xmx6g -jar pea-backend-1.0-SNAPSHOT-runner.jar 2>&1 >> log/pea.log & - 优化SWAP调度策略:
- 提高SWAP优先级,修改
/etc/fstab配置:
执行/swapfile swap swap defaults,pri=10 0 0swapon -a重新激活SWAP - 调整
vm.swappiness值,临时生效:sysctl vm.swappiness=80;永久生效则编辑/etc/sysctl.conf添加vm.swappiness=80,再执行sysctl -p
- 提高SWAP优先级,修改
- 限制Docker容器内存占用:
给每个容器设置内存上限,比如PostgreSQL设--memory=2g、Keycloak设--memory=3g、NGINX设--memory=512m,避免容器无限制占用内存。 - 实时监控内存状态:
使用htop、jstat等工具监控Java进程和容器的内存占用,根据实际运行情况进一步调整参数。
内容的提问来源于stack exchange,提问作者Paul
相关产品推荐
相关产品推荐

