Ubuntu 24.04.1 LTS 桌面版进程因OOM被杀死导致会话退出的解决求助
问题背景
我在Ubuntu 24.04.1 LTS桌面版上运行一个Python进程,它会占用大量内存资源:运行约1小时的过程中,能正常使用128GB全部物理内存和256GB的NVMe swap空间,但当swap用量接近300GB时,会话会突然终止并自动登出。我已经排除了硬件问题(更换过RAM和NVMe),也禁用了自动锁屏与休眠功能,当前swappiness值设为60。
从系统日志中可以找到明确的错误线索:
novato@novato-Super-Server:~$ sudo grep --text -ri 'killed process' /var/log/ /var/log/syslog:2024-11-28T23:54:31.369757-08:00 novato-Super-Server kernel: Out of memory: Killed process 6174 (python) total-vm:77951424kB, anon-rss:28399472kB, file-rss:116736kB, shmem-rss:2304kB, UID:1000 pgtables:70004kB oom_score_adj:200 /var/log/syslog:2024-11-28T23:57:43.092454-08:00 novato-Super-Server kernel: Out of memory: Killed process 8376 (python) total-vm:...
问题分析
从日志可以直接定位原因:内核的OOM Killer(内存不足杀手)启动并终止了Python进程。当系统的物理内存+交换空间(swap)不足以支撑所有进程的总内存需求时,内核会触发OOM机制,选择当前内存占用最高、oom_score_adj值较高的进程杀死,以此释放内存避免系统彻底崩溃。你的Python进程作为当前内存消耗大户,被优先终止,进而导致会话登出。
解决方案
以下是分级的解决思路,覆盖临时缓解到长期根治的不同场景:
1. 临时降低Python进程被OOM杀手选中的概率
OOM Killer会根据每个进程的oom_score_adj值(范围-1000到1000)选择目标:值越高越容易被杀死,值为-1000的进程会被彻底排除在OOM Killer的目标列表之外。
进程运行后调整
先通过ps aux | grep python找到Python进程的PID,然后执行:sudo echo -500 > /proc/[你的Python进程PID]/oom_score_adj将值设为-500(或更低的负数),能大幅降低该进程被杀死的优先级。注意:如果系统彻底内存耗尽,OOM Killer可能会转而杀死桌面会话进程(如gnome-shell),依然会导致登出。
启动进程时直接设置
可以用prlimit工具在启动Python进程时直接指定oom_score_adj:prlimit --oom-score-adj=-500 python your_script.py
2. 扩展临时swap空间(快速补充可用内存)
虽然你已有2TB swap,但可能存在swap分区碎片化、系统对swap的实际使用限制等问题,可以临时创建swap文件补充可用空间:
# 创建100GB的临时swap文件(可根据需求调整为200G等) sudo fallocate -l 100G /swap_temp # 设置严格权限(必须为600,否则系统拒绝使用) sudo chmod 600 /swap_temp # 格式化为swap格式 sudo mkswap /swap_temp # 启用该临时swap sudo swapon /swap_temp
这个swap文件是临时生效的,重启后会失效。如果需要永久生效,编辑/etc/fstab文件,添加一行:
/swap_temp none swap sw 0 0
3. 优化Python进程的内存使用(长期根治)
这是最彻底的解决方案,从根源上减少进程的内存消耗,避免触发OOM Killer:
- 用内存分析工具(如
memory_profiler、pympler)定位代码中的内存泄漏点; - 用生成器(generator)代替列表存储大数据集,避免一次性加载所有数据到内存;
- 及时释放不再使用的变量(用
del关键字,或手动触发垃圾回收gc.collect()); - 分块处理大文件/数据集,每次仅加载部分数据进行计算。
4. 调整OOM Killer行为,优先保护桌面会话
如果希望系统内存耗尽时优先杀死后台进程而非桌面会话,可以给桌面进程(如gnome-shell)设置更低的oom_score_adj值:
- 找到gnome-shell的PID:
pidof gnome-shell - 调整其
oom_score_adj值:
这样OOM Killer会彻底跳过桌面进程,转而选择其他内存大户(如你的Python进程或其他后台进程)。sudo echo -1000 > /proc/[gnome-shell的PID]/oom_score_adj
5. 调整swappiness值(优化内存/swap使用策略)
当前swappiness值为60,代表系统会在物理内存用到40%左右时开始使用swap。可根据需求调整:
- 若希望系统更积极使用swap(尽量保留物理内存给系统进程),可调高至80:
sudo sysctl vm.swappiness=80 - 若希望系统优先使用物理内存、少用swap,可调低至10:
要让设置永久生效,编辑sudo sysctl vm.swappiness=10/etc/sysctl.conf文件,添加或修改一行:vm.swappiness=80(替换为你需要的值)。
备注:内容来源于stack exchange,提问作者Calvin Kao

