摘要
在 GPU 计算中普遍存在的棘手问题:nvidia-smi 命令显示显存已被大量占用,但在进程列表中却看不到任何对应的计算任务。这种“幽灵”占用现象会导致新的任务因 CUDA out of memory 错误而无法启动,严重影响 GPU 资源的利用率。本文将分析该问题的根本原因,并提供一套行之有效的两步解决方案,通过 fuser 命令强制终止隐藏进程,并使用 ipcrm 清理残留的共享内存段,从而彻底释放被占用的 GPU 资源。

一、 问题诊断与现象
在管理多用户 GPU 服务器或运行长时间的深度学习任务时,管理员和开发者常常会遇到以下场景:
- 执行
nvidia-smi命令,发现一块或多块 GPU 的显存使用量(Used Memory)居高不下。 - 然而,在下方的进程信息(Processes)列表中,却找不到任何与该显存占用量匹配的 PID。列表可能是空的,或者只有一些占用显存极小的进程(如 Xorg)。
- 当尝试在该 GPU 上启动新的计算任务时,程序会立刻报错,提示显存不足(
CUDA out of memory),尽管从nvidia-smi的进程列表来看,GPU 应该是空闲的。
这种显存被占用但进程“隐身”的现象,我们称之为“幽灵”显存占用。
二、 根源分析:为何进程会“隐身”?
这个问题的根本原因在于 GPU 资源未能被正常释放。通常由以下两种情况导致:
-
进程异常终止:当一个正在使用 GPU 的程序(如 Python 脚本)被非正常方式杀死(例如,使用
kill -9,或程序自身崩溃),它可能没有机会执行清理代码来通知 NVIDIA 驱动程序释放其占用的显存。进程本身已经死亡,但其在 GPU 上分配的资源句柄却成了“孤儿”,继续被驱动程序锁定。 -
残留的共享内存段 (IPC):许多现代计算框架(特别是使用多进程数据加载的 PyTorch)会利用进程间通信(IPC)中的共享内存(Shared Memory)来提高效率。当主进程异常退出时,它所创建的共享内存段可能不会被系统自动回收。如果这些内存段与 GPU 资源相关联,它们就会像“僵尸”一样继续占用显存,而创建它们的父进程已经不复存在,因此
nvidia-smi无法将其归属到任何一个活动的 PID。
nvidia-smi 工具主要通过查询当前活动的进程来展示 GPU 使用情况,因此无法侦测到这种由已死亡进程或残留IPC段导致的资源占用。
三、 解决方案:两步彻底释放 GPU 资源
要解决此问题,需要手动介入,从更底层的系统层面识别并清理这些残留的资源句柄。
第 1 步:识别并强制终止所有与 GPU 设备文件交互的进程
操作系统将 GPU 设备抽象为一系列设备文件,通常位于 /dev/nvidia*。任何正在使用 GPU 的进程,无论是否在 nvidia-smi 中可见,都必然会与这些设备文件进行交互。我们可以利用 fuser 工具来找到并杀死这些进程。
-
查看占用进程 (可选,用于诊断)
执行以下命令,可以详细列出当前正在访问 NVIDIA 设备文件的所有进程及其用户。sudo fuser -v /dev/nvidia*fuser: 一个用于识别哪些进程正在使用指定文件、文件系统或套接字的工具。-v: (Verbose) 详细模式,会输出类似ps命令格式的进程信息。/dev/nvidia*: 匹配所有 NVIDIA 设备文件,包括/dev/nvidia0,/dev/nvidia1,/dev/nvidiactl等。
-
强制终止所有占用进程
执行以下命令,fuser会向所有找到的进程发送SIGKILL信号,强制终止它们。sudo fuser -k /dev/nvidia*-k: (Kill) 杀死所有访问该文件的进程。
通常,执行完这一步后,大部分“幽灵”显存占用会被释放。
第 2 步:清理残留的 NVIDIA 共享内存段
如果第一步未能完全解决问题,说明极有可能是残留的 IPC 共享内存段在作祟。我们需要找到这些内存段并手动删除它们。
下面这条命令组合可以自动化地完成这个过程:
sudo ipcs -m | grep nvidia | awk '{print $2}' | xargs -I {} sudo ipcrm -m {}
命令解析:
sudo ipcs -m: 列出当前系统中所有的共享内存段 (-m)。| grep nvidia: 通过管道将ipcs的输出传递给grep,筛选出那些可能与 NVIDIA 相关的内存段(这是一种有效的启发式搜索,因为相关内存段的属主或权限信息中常包含 “nvidia”)。| awk '{print $2}': 对筛选后的结果,使用awk工具提取第二列,即共享内存段的 ID (shmid)。| xargs -I {} sudo ipcrm -m {}:xargs会接收通过管道传递过来的每一个 shmid,并为每一个 ID 执行一次sudo ipcrm -m <shmid>命令。ipcrm -m是专门用于删除共享内存段的命令。
执行完这条命令后,所有与 NVIDIA 相关的残留共享内存段都将被清理。

四、 总结与验证
完成以上两个步骤后,再次执行 nvidia-smi。此时,您应该会看到之前被“幽灵”占用的显存已经被完全释放,GPU 恢复到了干净的空闲状态,可以正常接受新的计算任务。
- 核心流程:首先使用
fuser -k终结与 GPU 设备文件关联的一切进程,然后使用ipcs和ipcrm的组合命令清理可能残留的共享内存段。 - 适用场景:该方法对于因程序崩溃、SSH 会话意外断开、
kill -9强杀进程等原因导致的 GPU 资源无法释放问题,尤其有效。 - 最佳实践:为避免此类问题的频繁发生,建议在编写计算程序时,使用
try...finally或with语句来确保即使在代码异常时也能执行资源清理逻辑,实现程序的“优雅退出”。

被折叠的 条评论
为什么被折叠?



