Files

175 lines
10 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# GpuMemTool — Windows 显存监控与释放工具
基于 `nvidia-smi` + Windows 性能计数器,列出每个进程占用多少显存,可一键结束进程释放显存,并带显存 / GPU 占用率实时曲线监测。零依赖:系统自带 Windows PowerShell 5.1 + WinForms 即可运行。
本仓库包含两个版本:
| 版本 | 文件 | 说明 |
| --- | --- | --- |
| v1.1 | `GpuMemTool.ps1` / `GpuMemTool.exe` | 稳定版,单文件 exe(约 180 KB),双击即用 |
| v2.0 | `new1022/GpuMemTool.ps1` | 性能优化版:采集单轮 2433ms → 约 420ms(GPU 空闲)/ 970ms(GPU 忙),并修复采集超时导致的背靠背采样问题 |
> v2.0 的详细改动见脚本头部注释。
---
## v1.1 版本说明(根目录文件)
一个面向 Windows 的轻量显存(VRAM)监测与释放工具:**列出每个进程占用了多少显存,并可直接结束进程回收显存**,同时提供显存 / GPU 占用率的实时曲线监测。
基于 `nvidia-smi` + Windows 性能计数器,**零依赖** —— 只用系统自带的 Windows PowerShell 5.1 + WinForms,不需要安装 Python、.NET SDK 或任何第三方库。
**交付形态:单个 `GpuMemTool.exe`(约 180 KB),双击即用,启动时自动请求管理员权限。**
脚本已内嵌在 exe 内部,不需要附带任何其他文件。
> 本文件属于显存工具,与同目录的奶蛙桌宠项目(`README.md` / `src/` / `dist/`)无关。
## 文件说明
| 文件 | 作用 |
| --- | --- |
| **`GpuMemTool.exe`** | **交付主程序:单文件、免安装、双击运行**(内嵌脚本 + 图标 + UAC 提权逻辑) |
| `GpuMemTool.ps1` | 源码(可读可改;运行效果与 exe 完全一致,也会自己请求 UAC) |
| `RunAsAdmin.bat` | 备选入口:双击提权运行 `GpuMemTool.ps1` |
| `GpuMemTool-README.md` | 本说明 |
> 只需要 `GpuMemTool.exe` 一个文件就能用,其余文件可以删除/保留随意。
## 使用方法
1. **双击 `GpuMemTool.exe`** → 弹出 UAC 窗口(标题为 `GpuMemTool.exe`)→ 点「是」→ 主界面出现。
- 点「否」也不会报错:程序会继续以普通权限运行,界面右上角显示红色提示,
可随时点「以管理员身份重启」再试(只是部分进程无法结束)。
2. 首次启动约 5~15 秒完成性能计数器初始化(界面有提示),随后进入实时刷新。
### exe 的运行细节(透明说明)
- 启动时会把内嵌脚本释放到 `%LOCALAPPDATA%\GpuMemTool\GpuMemTool.ps1`(每次校验内容,
一致则不重写),然后用系统自带的 Windows PowerShell 运行它;
- 启动诊断日志:`%LOCALAPPDATA%\GpuMemTool\launcher.log`(仅在启动异常时才有用);
- exe 是免安装的绿色程序,不写注册表、不建服务;删除 exe 即可卸载
(如需彻底清理,再删掉上面那个 `%LOCALAPPDATA%\GpuMemTool` 目录即可);
- exe 未做代码签名,从本机运行不会有 SmartScreen 提示;若通过网络/U盘拷贝过来可能被
标记为「来自 Internet」,此时右键 → 属性 → 勾选「解除锁定」即可。
## 界面说明
- **顶部工具栏**:刷新间隔(1/2/3/5/10 秒)、自动刷新、「只看显存 ≥ 50MB」过滤、
立即刷新(F5)、结束选中进程(Delete)、强制结束、导出监测数据;右上角显示占用最高的进程。
- **6 个指标卡片**:显存占用(已用/总量 + 进度条,≥70% 变黄、≥90% 变红)、GPU 核心利用率、
显存带宽利用率、GPU 温度、功耗、**进程显存合计**(并显示「未归属(驱动/系统)」的部分)。
- **进程列表**:PID、进程名、显存 (MB)、显存占比、GPU 占用 %、数据来源、窗口标题/命令行、
可执行文件路径。**点击任意表头即可排序**(默认按显存从大到小)。
- **实时曲线**:蓝色为显存占用(左轴 MB),紫色为 GPU 利用率(右轴 %),红色虚线为 90% 警戒线。
- **状态栏**:最近更新时间、进程数、采集异常提示、本次已释放的显存总量。
### 右键菜单 / 快捷键
| 操作 | 说明 |
| --- | --- |
| 结束进程 / `Delete` | 结束选中进程(默认**先尝试正常关闭窗口**,3 秒内没退出再终止) |
| 强制结束 | 直接 `Stop-Process -Force` |
| 复制 PID | 把选中进程的 PID 复制到剪贴板 |
| 打开文件所在位置 | 在资源管理器中定位该进程的可执行文件 |
| 查看详细信息 / 双击行 | 显示命令行 + `tasklist /V` 的完整信息 |
| `F5` | 立即刷新 |
支持 Ctrl / Shift 多选,可一次结束多个进程。
## 进程保护机制(安全设计)
结束进程前会依次检查,避免误杀:
1. **禁止结束**(`BlockNames`):`System`、`Idle`、`Registry`、`Memory Compression`、`csrss`、
`wininit`、`services`、`lsass`、`smss`、`winlogon`、`fontdrvhost`、`MsMpEng` 等 ——
结束它们会导致系统蓝屏或不可恢复。
2. **保护自身**:本工具自己的 PID,以及直接父进程(控制台宿主 `powershell.exe` / `cmd.exe` /
Windows Terminal,结束它会连带关掉本窗口)。
3. **二次确认**(`WarnNames`):`dwm`、`explorer`、`svchost`、`SearchHost`、
`StartMenuExperienceHost` 等系统外壳进程 —— 允许结束,但要连续确认两次,并提示桌面可能闪烁。
4. **PID 复用保护**:真正结束前会重新读取该 PID 的进程名,若与列表里的名字不一致
(说明 PID 已被系统复用给别的进程),则跳过,避免误杀。
5. 确认框会列出每个待结束进程的名字、PID、占用显存,以及预计可释放的总量。
## 结束进程的真实行为(重要)
`Stop-Process` 有个坑:**它可能"假成功"** —— 调用没报错,但进程被驱动/反作弊挡住而不退出
(典型是卡死的游戏进程:只剩 1 个线程、工作集接近 0,却仍占着 1.6 GB 显存)。旧版本信了它的返回值,
于是显示"已结束"、进程却纹丝不动,看起来就是"按钮不生效"。
现在的处理流程是**三步 + 结果校验**:
1. 先尝试正常关闭窗口,3 秒内没退出就 `Stop-Process`;
2. **轮询确认进程是否真的消失**(不看返回值,只看事实);
3. 没消失就自动回退到 **WMI `Win32_Process.Terminate`** —— 这条路径由 SYSTEM 权限的 WMI 服务执行,
能结束一部分 `Stop-Process` 杀不掉的进程(实测:一个卡死的 1.6 GB 游戏进程就是这样被清掉的);
4. 仍然杀不掉时**如实报告**,并给出建议:按 `Win + Ctrl + Shift + B` 重启显卡驱动,
或重启系统。
所以现在无论成功还是失败,都会弹出一个结果对话框告诉你**到底发生了什么**,不会再"点了没反应"。
### 权限说明
- 结束**自己启动的**普通进程:普通权限通常就够;
- 结束**以管理员身份运行**的进程(很多游戏、部分软件):必须让本工具以管理员身份运行,
否则会得到 `Access is denied`(错误码 5);
- 程序启动时自己会请求 UAC;若你点了「否」,界面右上角会显示红色提示,
确认框里也会提前警告"结束其他用户的进程会失败"。
## 命令行 / 自动化用法
exe 与 ps1 都支持同样的参数(命令行模式**不会**弹 UAC):
```powershell
# 无界面自检:采集一次并打印 GPU 指标 + 逐进程显存表格(便于排错)
GpuMemTool.exe -SelfTest
# 结束指定进程(仍受保护名单约束;系统外壳进程需显式加 -Force 才会结束)
GpuMemTool.exe -KillPid 1234,5678 -Force
# 用源码运行等价写法
powershell -NoProfile -ExecutionPolicy Bypass -File GpuMemTool.ps1 -SelfTest
```
> 在 cmd/PowerShell 里直接敲 `GpuMemTool.exe -SelfTest` 就能看到输出(exe 会自动接回当前控制台)。
## 技术说明(为什么不能只用 nvidia-smi)
Windows(WDDM 模式)下,`nvidia-smi --query-compute-apps=pid,used_gpu_memory` 的
`used_gpu_memory` **通常返回 `[N/A]`** —— 只有 TCC 模式或纯 CUDA 上下文才有效。实测本机
RTX 5060 Laptop 上所有进程该项都是 `[N/A]`,所以**单靠 nvidia-smi 无法回答「哪个进程占用了多少显存」**。
本工具采用双数据源合并:
| 数据 | 来源 |
| --- | --- |
| 显存总量/已用/空闲、GPU 利用率、显存带宽利用率、温度、功耗 | `nvidia-smi --query-gpu=...` |
| 逐进程显存占用 | Windows 性能计数器 `Win32_PerfFormattedData_GPUPerformanceCounters_GPUProcessMemory` 的 **Local Usage** |
| 逐进程 GPU 占用 % | 同计数器集的 `GPUEngine` 的 `UtilizationPercentage`(按 PID 汇总) |
| CUDA 进程显存(若有) | `nvidia-smi --query-compute-apps`,与计数器值取较大者;来源列标注 `CUDA` / `WDDM` / `CUDA+WDDM` |
实测校验:逐进程合计 ≈ nvidia-smi 报告的已用量(例:合计 2377 MB vs 已用 2491 MB,
差值约 114 MB 属驱动/系统保留);界面把差值单独显示为「未归属(驱动/系统)」。
**采集性能**:首次采集需初始化性能计数器,约 5~15 秒(界面有提示);之后每次约 0.1~0.8 秒。
采集在独立 Runspace 中异步执行,界面不会卡顿。
## 常见问题
- **刚打开时曲线是空的?** 正常,前几秒在初始化计数器,界面会提示;第一轮数据到达即出曲线。
- **某个进程的显存很小或为 0?** 它可能只是短暂使用 GPU,或占用的是共享显存(Shared)。
本工具显示的是专用显存(Local / Dedicated)。
- **结束进程后显存没立刻下降?** 显存由驱动异步回收,通常 1~2 秒内刷新;也可能该进程还有子进程在占用。
- **列表里没有某个进程?** 只有「显存 ≥ 1MB 或 GPU 占用 ≥ 0.5%」的进程会被列出;
取消勾选「只看显存 ≥ 50MB」可看到全部。
- **多 GPU 机器**:GPU 级指标取第一块 GPU;Windows 性能计数器无法把进程映射到具体某块显卡,
因此**进程级数据是多块 GPU 的合计**。
- **提示找不到 nvidia-smi?** 程序仍可用(仅性能计数器数据),但 GPU 级指标不可用。
请确认已装 NVIDIA 驱动,或 `nvidia-smi.exe` 位于 `C:\Windows\System32`。
## 注意事项
- 结束进程会**立即丢失该进程未保存的数据**,请确认后再操作。
- 结束 `dwm.exe` / `explorer.exe` 会导致桌面、任务栏短暂闪烁或重启(Windows 会自动恢复),
正在运行的全屏程序可能受影响。
- 本工具不会自动结束任何进程,只有你点了按钮并确认后才会执行。