如何避免systemd服务启动的所有进程因单个子进程OOM被全部终止?
解决systemd服务子进程OOM导致全进程被杀死的问题
调整Slice的OOM策略
你当前配置的OOMPolicy=kill会让systemd在触发内存限制时直接终止整个slice内的所有进程。可以将其改为continue,把OOM决策交还给内核,由内核根据进程的OOM分数选择要杀死的目标:
OOMPolicy=continue MemoryMax=8G
这个配置不会让systemd主动终止整个slice,而是让内核OOM killer按规则处理单个进程。
正确设置进程OOM优先级
之前修改OOM分数无效,大概率是因为systemd服务进程会继承cgroup的OOM配置,或者修改方式有误。可以通过两种方式调整:
- 在服务单元(
.service文件)中为主进程设置高优先级(更低的OOM分数,更难被杀死):
[Service] OOMScoreAdjust=-1000 # 主进程几乎不会被OOM选中 ExecStart=/path/to/your/main/process
- 启动子进程时,通过
prctl命令单独设置其OOM分数(让子进程更容易被选中):
prctl --set-oom-score-adj 1000 /path/to/child/process
这样内核会优先杀死OOM分数高的子进程,而非主服务或其他正常子进程。
用systemd Scope优雅隔离子进程
如果手动创建cgroup不够简洁,可以用systemd-run为每个子进程自动创建临时的scope单元,实现轻量cgroup隔离:
systemd-run --user --scope --slice=your-service.slice /path/to/child/process
还能给单个子进程单独设置内存限制:
systemd-run --user --scope --slice=your-service.slice -p MemoryMax=2G /path/to/child/process
这种方式无需手动编写cgroup配置,由systemd自动管理,比手动建cgroup更优雅。
验证配置生效
修改配置后,需要重新加载systemd并重启服务:
systemctl daemon-reload systemctl restart your-service.service
可以通过cat /proc/[pid]/oom_score_adj查看进程OOM分数是否生效,或用systemd-cgtop监控cgroup内存使用情况。
内容的提问来源于stack exchange,提问作者vfivept
相关产品推荐
相关产品推荐

