Python multiprocessing.SharedMemory 创建失败报 OSError: Cannot allocate memory,根本原因是 Linux 系统 /dev/shm 默认仅64MB空间耗尽;需通过 mount -o remount,size=2g /dev/shm 临时扩容,或修改 /etc/fstab 永久生效,且必须配合 atexit 清理与唯一命名防残留。

Python multiprocessing.SharedMemory 创建失败报 OSError: Cannot allocate memory
这不是 Python 代码逻辑错误,而是系统级共享内存(/dev/shm)空间耗尽。Linux 默认只给 /dev/shm 分配 64MB,而多进程爬虫常批量创建 SharedMemory 实例(比如每个 worker 缓存一个页面 HTML),几轮 fork 后就撑爆。现象是 multiprocessing.shared_memory.SharedMemory 构造时直接抛 OSError: Cannot allocate memory,且 df -h /dev/shm 显示已满。
- 临时扩容:用 root 执行
mount -o remount,size=2g /dev/shm(重启失效) - 永久生效:编辑
/etc/fstab,把原有shm行改为shm /dev/shm tmpfs defaults,size=2g 0 0,再mount -o remount /dev/shm - 别依赖
ulimit -l:它管的是 mlock 内存锁,和 shm 无关 - Python 层无法 catch 这个错误——它发生在内核 mmap 阶段,
try/except OSError只能兜底,不能预防
VSCode Debug 模式下 multiprocessing 父子进程共享内存异常中断
在 VSCode 中按 F5 启动带 multiprocessing 的爬虫脚本,Debug 会卡死或子进程静默退出,控制台无报错。根本原因是 VSCode 的 Python 调试器(ptvsd 或 debugpy)默认启用 subprocess 拦截,但对 SharedMemory 对象的 fd 传递支持不完整,导致子进程拿到无效句柄,后续 shm.unlink() 或读写直接崩溃。
- 确认是否触发:运行前加
import os; print("SHM_FD:", os.environ.get('PYTHONPATH')),若子进程中该环境变量为空或被覆盖,大概率是调试器干扰 - 绕过方案:在
launch.json中显式禁用子进程调试:"subProcess": false - 更稳妥做法:开发阶段改用
if __name__ == '__main__':+multiprocessing.set_start_method('spawn'),避免 fork 时继承调试器状态 - 别在
SharedMemory对象上设断点——调试器可能尝试序列化它,引发不可逆损坏
爬虫 worker 多次运行后 SharedMemory 未释放导致 /dev/shm 残留文件堆积
SharedMemory 实例即使调用了 .close() 和 .unlink(),如果进程被 kill -9 或意外崩溃,/dev/shm/psm_* 文件仍会残留。下次运行时同名冲突(FileExistsError)或持续占用空间,最终拖垮整个系统。
- 强制清理命令:
find /dev/shm -name "psm_*" -delete 2>/dev/null(加2>/dev/null避免权限报错) - 代码层防护:创建前加唯一前缀(如
f"psm_{os.getpid()}_{int(time.time())}"),避免跨运行冲突 - 自动清理钩子:用
atexit.register(lambda: shm.close() or shm.unlink()),但仅对正常退出有效;崩溃场景必须依赖外部清理 - 监控手段:
ls -l /dev/shm | wc -l超过 50 就预警,说明有泄漏苗头
VSCode 终端里运行正常,但集成终端(Integrated Terminal)中启动就 OOM
不是 Python 问题,是 VSCode 集成终端本身内存限制叠加了 /dev/shm 分配失败的双重效应。集成终端由 VSCode 主进程托管,当它 spawn 出大量 Python 子进程并申请 shm 时,主进程 RSS 会同步飙升(Electron 渲染进程吃掉额外内存),一旦超过 --max-memory 上限,整个窗口卡死,连终端输出都冻结。
立即学习“Python免费学习笔记(深入)”;
- 验证方法:终端中执行
ps aux | grep code | grep -v grep,看code主进程 RSS 是否 >2.5GB - 立即缓解:关闭所有非必要插件,然后从终端手动启动:
code --disable-extensions --max-memory=4096 . - 长期规避:爬虫类任务一律在外部终端(iTerm/Terminal.app/Windows Terminal)中运行,VSCode 仅作编辑用
- 别信
python -m venv能解决——虚拟环境不隔离 shm,问题根源在系统层
SharedMemory 怎么写,而是它如何与 VSCode 的多进程模型、Linux 的 shm 管理机制、以及你 Ctrl+C 的时机发生隐性耦合。一个没 unlink() 的实例,一次没处理的 SIGKILL,都可能让 /dev/shm 在后台悄悄长出几十个僵尸文件。


















