windows如何查看GPU显存被什么软件占用
Created on: August 13, 2025
Created on: August 13, 2025
windows如何查看GPU显存被什么软件占用
在 Windows 下查看 GPU 显存被哪些软件占用,可以用以下几种方法:
Ctrl + Shift + Esc
打开 任务管理器。Win + R
→ 输入 resmon
→ 回车。NVIDIA 用户
nvidia-smi
(需安装 NVIDIA 驱动或 CUDA 工具包):
会显示每个进程的显存占用和 PID。powershellnvidia-smi
AMD 用户
✅ 推荐做法:
如果只是快速查看 → 用 任务管理器 就够了。
如果要找显存“吃”得多的后台程序 → 用 nvidia-smi / Radeon Software 更准确。
如果你愿意,我可以帮你写一个 Windows PowerShell 脚本,一键列出所有进程的显存占用情况,比任务管理器更详细。
你要我帮你写这个脚本吗?这样可以直接运行查看。
|=========================================+========================+======================|
| 0 NVIDIA GeForce RTX 4070 ... WDDM | 00000000:01:00.0 On | N/A |
| N/A 65C P4 10W / 130W | 6306MiB / 8188MiB | 6% Default |
| | | N/A |
+-----------------------------------------+------------------------+----------------------+
+-----------------------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=========================================================================================|
| 0 N/A N/A 2508 C+G ...xyewy\ShellExperienceHost.exe N/A |
| 0 N/A N/A 4224 C+G C:\Windows\explorer.exe N/A |
| 0 N/A N/A 13064 C+G ...easel-0.17.4\WeaselServer.exe N/A |
| 0 N/A N/A 14796 C+G ...Telegram Desktop\Telegram.exe N/A |
| 0 N/A N/A 14880 C+G ...ef.win7x64\steamwebhelper.exe N/A |看不到,为什么有6G占用
你在 nvidia-smi
输出里看到 6GB 显存被占用,但进程列表全是 N/A
,这是因为你当前的驱动是 WDDM 模式(Windows Display Driver Model),在这个模式下 nvidia-smi
无法显示大部分桌面图形进程的显存占用,只能在 TCC 模式 或 Linux 下看到完整信息。
在 WDDM 下,有几个原因会导致这种情况:
显卡用作桌面渲染
Windows 桌面、动画、字体渲染、壁纸等会占用一部分显存,但这些进程(如 dwm.exe
)在 nvidia-smi
下经常显示不出来。
视频缓冲与纹理缓存
浏览器、视频播放、甚至任务栏小部件都会缓存纹理到显存。
显卡驱动与系统保留显存
NVIDIA 驱动和 Windows 会预留一部分显存用于图形系统,不会列在进程列表里。
后台应用 / 隐藏进程
有些应用使用 GPU 做加速,但不会被 nvidia-smi
在 WDDM 模式下列出来(比如某些 UWP 应用、硬件加速的后台服务)。
由于 nvidia-smi
在 WDDM 模式下信息不全,可以换其他方法:
任务管理器
Ctrl + Shift + Esc
→ “进程”标签 → 在表头右键 → 勾选“GPU 内存”列Process Explorer(Sysinternals 工具)
NVIDIA 控制面板 / GeForce Experience
部分版本在“系统信息”里可以显示显存使用进程
第三方工具
如果你愿意,我可以帮你做一个 PowerShell 脚本,它会用 WMI 查询所有进程的 GPU 显存占用,比 nvidia-smi
在 WDDM 下更全,适合定位“吃显存”的后台程序。
这样你就能知道那 6GB 里具体是哪些软件占的。
你要我帮你写这个脚本吗?这样运行一次就能列出来。
写
好嘞!下面是一份在 Windows 10/11(WDDM 模式) 下可用的 PowerShell 脚本,直接按进程统计 显存占用(Dedicated/Shared),弥补 nvidia-smi
在 WDDM 下显示 N/A
的问题。
Get-GpuVramUsage.ps1
powershellpowershell -ExecutionPolicy Bypass -File .\Get-GpuVramUsage.ps1
powershell.\Get-GpuVramUsage.ps1 -Watch
powershellparam( [switch]$Watch, [int]$IntervalSeconds = 2, [int]$Top = 50 ) function Get-GpuCountersAvailable { try { $c = Get-Counter -ListSet 'GPU Process' -ErrorAction Stop return $true } catch { return $false } } function Get-GpuProcessVramOnce { # 需要的性能计数器(显存:专用/共享) $counters = @( '\GPU Process(*)\Dedicated Usage', '\GPU Process(*)\Shared Usage' ) try { $samples = (Get-Counter -Counter $counters -ErrorAction Stop).CounterSamples } catch { Write-Warning "未能获取 \GPU Process\* 性能计数器。请确认系统为 Win10/11 较新版本并安装了 WDDM 驱动。" return @() } # 组装:PID -> {Name, DedicatedBytes, SharedBytes} $byPid = @{} foreach ($s in $samples) { # CounterPath 形如: \\MACHINE\gpu process(processname (1234))\dedicated usage $instance = $s.InstanceName if (-not $instance -or $instance -eq "_Total") { continue } if ($instance -match '$(\d+)$$') { $pid = [int]$matches[1] } else { continue } if (-not $byPid.ContainsKey($pid)) { $byPid[$pid] = [ordered]@{ PID = $pid Name = $null DedicatedBytes = 0 SharedBytes = 0 Path = $null } } $entry = $byPid[$pid] # 名称先用实例名前半段兜底,后面再用 Get-Process 修正 if (-not $entry.Name) { $namePart = $instance -replace '\s*$\d+$$','' $entry.Name = $namePart } $value = [double]$s.CookedValue if ($s.Path -match '\\Dedicated Usage$') { $entry.DedicatedBytes = [math]::Max($entry.DedicatedBytes, $value) } elseif ($s.Path -match '\\Shared Usage$') { $entry.SharedBytes = [math]::Max($entry.SharedBytes, $value) } } # 用 Get-Process 丰富进程信息(进程路径、友好名等) foreach ($pid in $byPid.Keys) { try { $p = Get-Process -Id $pid -ErrorAction Stop if ($p) { if ($p.Path) { $byPid[$pid].Path = $p.Path } # 用真实进程名覆盖 if ($p.ProcessName) { $byPid[$pid].Name = $p.ProcessName } } } catch {} } # 转为对象并换算单位 $rows = foreach ($kv in $byPid.GetEnumerator()) { $o = $kv.Value [pscustomobject]@{ Name = $o.Name PID = $o.PID 'GPU_DedicatedMB' = [math]::Round($o.DedicatedBytes / 1MB, 1) 'GPU_SharedMB' = [math]::Round($o.SharedBytes / 1MB, 1) Path = $o.Path } } # 排序,过滤掉全 0 的行 $rows | Where-Object { $_.GPU_DedicatedMB -gt 0 -or $_.GPU_SharedMB -gt 0 } | Sort-Object -Property GPU_DedicatedMB -Descending } function Get-AdapterVramSummary { # 适配器级显存使用/上限(可选,用于总览) $sum = $null try { $a = Get-Counter '\GPU Adapter Memory(*)\Dedicated Usage','\GPU Adapter Memory(*)\Dedicated Limit' -ErrorAction Stop $usage = @{} $limit = @{} foreach ($s in $a.CounterSamples) { if ($s.Path -match '\\Dedicated Usage$') { $usage[$s.InstanceName] = [double]$s.CookedValue } elseif ($s.Path -match '\\Dedicated Limit$') { $limit[$s.InstanceName] = [double]$s.CookedValue } } $sum = foreach ($k in $usage.Keys) { [pscustomobject]@{ Adapter = $k DedicatedUsedMB = [math]::Round($usage[$k]/1MB,1) DedicatedLimitMB = if ($limit.ContainsKey($k)) { [math]::Round($limit[$k]/1MB,1) } else { $null } } } } catch {} return $sum } if (-not (Get-GpuCountersAvailable)) { Write-Warning "未检测到 'GPU Process' 性能计数器。你的系统可能过旧或缺少图形驱动性能计数器。" Write-Host "可选替代:" Write-Host " 1) 任务管理器 -> 进程 -> 右键表头 -> 勾选“GPU 内存”" Write-Host " 2) Sysinternals Process Explorer -> View -> Select Columns -> GPU -> 勾选 GPU Memory" Write-Host " 3) NVIDIA 用户可配合 nvidia-smi(WDDM 限制下仍可能 N/A)" exit 1 } if ($Watch) { while ($true) { Clear-Host $sum = Get-AdapterVramSummary if ($sum) { Write-Host "=== 适配器显存总览(Dedicated) ===" $sum | Format-Table -AutoSize Write-Host "" } $rows = Get-GpuProcessVramOnce if (-not $rows -or $rows.Count -eq 0) { Write-Host "当前未检测到进程显存占用(或计数器无数据)。" } else { $rows | Select-Object -First $Top | Format-Table -AutoSize } Write-Host "" Write-Host ("提示:按 Ctrl+C 结束。下一次刷新:{0}s" -f $IntervalSeconds) Start-Sleep -Seconds $IntervalSeconds } } else { $sum = Get-AdapterVramSummary if ($sum) { Write-Host "=== 适配器显存总览(Dedicated) ===" $sum | Format-Table -AutoSize Write-Host "" } $rows = Get-GpuProcessVramOnce if (-not $rows -or $rows.Count -eq 0) { Write-Host "未检测到进程显存占用(或计数器暂无数据)。" } else { $rows | Select-Object -First $Top | Format-Table -AutoSize } }
\GPU Process(*)\Dedicated Usage
/ \GPU Process(*)\Shared Usage
Dedicated
对应我们通常说的 显存(显卡专用内存);Shared
是与系统内存共享的部分。GPU Process
计数器:
nvidia-smi
的 总显存 与 进程(但在 WDDM 下可能仍显示 N/A
)。需要我帮你把输出保存成 CSV/TSV(便于发我看)或者加上进程白名单/黑名单过滤也可以,我直接给你改好版本。
PS C:\Users\55821\Downloads\Compressed> powershell -ExecutionPolicy Bypass -File .\gpu.ps1
WARNING: 未检测到 'GPU Process' 性能计数器。你的系统可能过旧或缺少图形驱动性能计数器。
可选替代:
明白了:你的系统里 “GPU Process” 性能计数器不可用,所以我那份脚本没法拿到“每进程显存(Dedicated/Shared)”。这在某些 Win10/Win11 版本 + 显卡驱动组合上会发生(尤其是独显直连/老驱动/企业镜像)。下面给你三个可行方案:
nvidia-smi
看到的那 6GB 里是谁占的)。小提示:
dwm.exe
、浏览器、播放器、Steam/游戏启动器、某些 IM(Telegram/Discord)都可能长期占显存;把每个进程关掉/重开即可验证释放情况。
powershellwpr -cancel 2>$null wpr -start GPU -filemode # 复现“显存被吃”的场景 10~30 秒 wpr -stop "%USERPROFILE%\Desktop\gpu_trace.etl"
gpu_trace.etl
:
这个脚本做两件事:
\GPU Adapter Memory\Dedicated Usage/Limit
给你总显存占用(印证 nvidia-smi
的 6GB)。\GPU Engine(*)\Utilization Percentage
找到当下最可能的元凶进程(哪怕拿不到显存数,也能锁定对象),再去任务管理器/Process Explorer 里核对该进程的显存。运行方法:保存为
GpuWhoUses.ps1
,在 PowerShell 里执行
powershell -ExecutionPolicy Bypass -File .\GpuWhoUses.ps1 -Top 15 -Watch
(每2秒刷新)
powershellparam( [switch]$Watch, [int]$IntervalSeconds = 2, [int]$Top = 20 ) function Get-AdapterVramSummary { try { $c = Get-Counter '\GPU Adapter Memory(*)\Dedicated Usage','\GPU Adapter Memory(*)\Dedicated Limit' -ErrorAction Stop } catch { return $null } $usage = @{} $limit = @{} foreach ($s in $c.CounterSamples) { if ($s.Path -match '\\Dedicated Usage$') { $usage[$s.InstanceName] = [double]$s.CookedValue } elseif ($s.Path -match '\\Dedicated Limit$') { $limit[$s.InstanceName] = [double]$s.CookedValue } } foreach ($k in $usage.Keys) { [pscustomobject]@{ Adapter = $k DedicatedUsedMB = [math]::Round($usage[$k]/1MB,1) DedicatedLimitMB = if ($limit.ContainsKey($k)) { [math]::Round($limit[$k]/1MB,1) } else { $null } } } } function Get-TopGpuUsersByEngine { # 用 GPU Engine 利用率定位“嫌疑进程”(没有 GPU Process 计数器时的退路) $engineCounters = '\GPU Engine(*)\Utilization Percentage' try { $samples = (Get-Counter -Counter $engineCounters -ErrorAction Stop).CounterSamples } catch { Write-Warning "无法读取 \GPU Engine\* 计数器。" return @() } $agg = @{} foreach ($s in $samples) { $inst = $s.InstanceName if (-not $inst -or $inst -eq "_Total") { continue } # 实例名通常形如:engtype_3D (pid_12345) / engtype_VideoDecode_0 (pid_6789) if ($inst -match 'pid[_\s]?(\d+)') { $pid = [int]$matches[1] if (-not $agg.ContainsKey($pid)) { $agg[$pid] = 0.0 } $agg[$pid] += [double]$s.CookedValue } } $rows = foreach ($pid in $agg.Keys) { $name = "(exited)" $path = $null try { $p = Get-Process -Id $pid -ErrorAction Stop $name = $p.ProcessName $path = $p.Path } catch {} [pscustomobject]@{ PID = $pid Name = $name GPU_Util_SumPct = [math]::Round($agg[$pid],1) # 各引擎利用率求和 Path = $path } } $rows | Sort-Object GPU_Util_SumPct -Descending } function RenderOnce($top) { $sum = Get-AdapterVramSummary if ($sum) { Write-Host "=== 适配器显存总览(Dedicated) ===" $sum | Format-Table -AutoSize Write-Host "" } else { Write-Host "未能读取适配器显存总览(可能计数器缺失)。" } $suspects = Get-TopGpuUsersByEngine if ($suspects.Count -gt 0) { Write-Host "=== 当前最可能的显存占用进程(按 GPU 引擎利用率排序) ===" $suspects | Select-Object -First $top | Format-Table -AutoSize Write-Host "" Write-Host "提示:将上面排前的进程在“任务管理器/Process Explorer”里查看列:GPU 内存(Dedicated),能直接看到它具体占了多少显存。" } else { Write-Host "当前未检测到明显的 GPU 引擎活动。若仍有高显存占用,可能是后台缓存/驱动保留或应用挂起但占显存。" } } if ($Watch) { while ($true) { Clear-Host RenderOnce -top $Top Write-Host ("按 Ctrl+C 结束。{0}s 后刷新…" -f $IntervalSeconds) Start-Sleep -Seconds $IntervalSeconds } } else { RenderOnce -top $Top }
如果你愿意,我也可以把 Process Explorer 的下载链接、WPA 打开视图的具体菜单路径,以及 “一键导出 CSV” 的脚本再补上;或者你把 GpuWhoUses.ps1
的输出/截图发我,我帮你一起定位“6GB”是被谁吃掉的。