LR疯狂吃显存导致系统严重卡顿?—— 记为此尝试的历程与最终可行的“欺骗”
24GB 显存的显卡被修图应用吃满、溢出、整机卡顿—— 最终的解不是”封顶”,而是只谎报一个数字,让应用自己收敛水位。
- Lightroom Classic 的显存分配是「水位线式贪婪」:它把 GPU 内存池填到接近「预算」才停手, 24GB 的卡也照吃不误,溢出到共享显存后拖慢整个系统。
- 想直接「拒绝分配」来封顶?只会得到 纯红图片——它不处理显存分配失败。
- 真正有效的做法:只谎报一个数字——DXGI
QueryVideoMemoryInfo返回的Budget。 把它报小一号(本案例最终 10GB),Lightroom 自己就把水位稳住:整卡占用 ≈70%、零卡顿、零红图、零功能损失。 - 实现是一个应用目录内的
dxgi.dll代理(约两百多行核心逻辑),配置两行,重启应用生效,卸载 = 删文件。
01现象:24GB 显存,照样被吃满
一台 Win11 机器:64GB 内存 + 24GB 显存的 AMD 独显。症状:
- Lightroom Classic 开着 GPU 加速修图一段时间后,显存被逐渐占满(整卡 90%+);
- 随后开始溢出到共享显存(系统内存充当显存后备),整机明显卡顿;
- 关掉 Lightroom 立刻恢复。换小显卡的机器反而没这么难受——
先做的第一件事是把测量做扎实。
02测量:厂商无关的「显存三只眼」
没有厂商工具也没关系,Windows 自带的性能计数器就是任务管理器的数据源:
PowerShellGet-Counter '\GPU Adapter Memory(*)\Dedicated Usage' # 整卡专用显存 Get-Counter '\GPU Adapter Memory(*)\Shared Usage' # 溢出到共享的部分 Get-Counter '\GPU Process Memory(*)\Dedicated Usage' # 按进程(实例名含 PID)
两个坑先记下:
- 别用 WMI 的
AdapterRAM:32 位截断,管你多大的卡都报 4095MB; - LUID 会变:按进程查显存时不要硬编码适配器 LUID,否则某次重启后采样会静默全 0。
测出来的核心事实:
| 显卡 | Lightroom 占用 |
|---|---|
| 4GB | ~90% |
| 8GB | ~7 / 8GB |
| 12GB | ~11.8 / 12GB |
| 本机 24GB | 最高 25.6GB(溢出) |
03死路:硬上限与「全盘谎言」
尝试 A:硬上限(拒绝分配)
我们在应用目录放代理 DLL,拦截 D3D11/D3D12 的资源创建,超过天花板就返回
E_OUTOFMEMORY。显存确实被封顶了——但 Lightroom 画出纯红图片:
它根本没有写「分配失败」的处理分支。三次不同天花板,三次红图,结论闭环:
尝试 B:谎报一切数字
把专用显存、共享显存、DXGI 预算、显卡型号、物理内存挨个伪装了一遍:
- 「系统信息」面板里数字都变了(说明谎报生效);
- 分配行为纹丝不动。
当时得出的(后来被修正的)结论:Windows 用户态没有 per-process 显存上限 API, 唯一强制手段是「拒绝分配」,而这条路被应用堵死了。
04转折点:其实它有完整的显存管理
当真去读应用自己的日志和二进制之后,画风突变:
- 引擎里有一个预算监视线程,监听系统的「显存预算变化」通知,并实时查询
QueryVideoMemoryInfo; - 运行日志里能看到它的池 / 缓存预算:基线约为报告预算的 86%(如 21.3GB / 24.9GB);
- 日志里大量出现
TrimFootprint: x MB purged from pools——它会主动清理内存池(单次最高近 17GB); - 它的 AI 子系统还有「内存受限 / 模型常驻」两档策略。
05解决思路:不砌墙,调水位
既然它的行为是 预算 → 水位 的自适应函数,那就只改这一个输入:
在QueryVideoMemoryInfo的应答里,把Budget从真实的 ~24GB 谎报为一个更小的值(本案例最终 10GB)。
一切照旧:分辨率、位深、功能全不变;只是它「以为的显卡」小了一号, 于是池预算、清理阈值全部等比例地更保守。
06实验数据与档位收敛
| 指标 | 基线(真值) | 初版:三值都压到 8GB | 最小集:只压 Budget=8GB | 回测:Budget=16GB(轻负载) | 最终:Budget=10GB(重负载复测) |
|---|---|---|---|---|---|
| 应用真实占用峰值 | 25,642 MB | 13,902 MB | 12,613 MB | 15,025 MB | 13,407 MB |
| 整卡专用峰值 | 24,315 MB(98.9%) | 15,305 MB | 12,374 MB | 18,779 MB(≈77%) | 17,158 MB(≈70%) |
| 分配拒绝 / 红图 / 报错 | — | 0 / 无 | 0 / 无 | 0 / 无 | 0 / 无 / 无 |
数据口径:Windows 性能计数器(逐 8 秒采样)+ 应用自身日志;峰值为会话内最大值。
07原理复盘:为什么这一招成立
- 应用本来就是「按预算自适应」的:同一套逻辑,在小显存卡上它会自动更保守 (这也是为什么 8GB 卡能正常工作的原因);
- 预算越低估,它的池预算越小、清理越勤;预算越接近真实容量,就越接近「给多少吃多少」;
- 全程没有任何分配被拒绝,所以永远踩不到它缺失的「OOM 错误处理」路径—— 这正是它比「硬上限」优雅的地方。
08教程:最小修改做法
8.1 原理
- 应用目录中的
dxgi.dll会被优先加载(dxgi不是系统 KnownDLL); - 代理转发全部导出函数到系统真正的 dxgi,保持完全兼容;
- 只做一处补丁:应用创建 DXGI 工厂拿到适配器对象后,把它虚表上的
QueryVideoMemoryInfo(槽位 14) 换成我们的版本; - 我们的版本先调用原函数,然后把应答里的
Budget(以及两个 Reservation 字段) 截断到配置值,其余原样返回; - 配置放
%TEMP%\lr_vram_cap.txt,进程启动时读一次。
8.2 步骤
- 获取 / 构建代理(仓库结构:
dxgi_proxy.cpp+ 转发桩trampolines.asm+build.bat)。 工具链:VS 生成工具 + Windows SDK。构建后用dumpbin /exports对比系统C:\Windows\System32\dxgi.dll的导出表(本环境为 20 个),必须一一对齐, 少一个都会导致应用启动失败。 - 放入安装目录:
<Lightroom 安装目录>\dxgi.dll。 - 写配置(
%TEMP%\lr_vram_cap.txt):INI; 只谎报预算一个数字 budget_mb = 10240 ; 谎报的显存预算(MB);0 = 关闭 desc_mb = 0 ; 谎报专用显存(0 = 真实值,本方案不需要) shared_mb = 0 ; 谎报共享显存(0 = 真实值) log = 1 ; 写日志到 %TEMP%\dxgi_proxy.log
- 完全退出并重启 Lightroom(配置只在启动时读一次)。
- 验证:看
%TEMP%\dxgi_proxy.log,应出现reportedBudget=10240MB而realBudget仍是真实值。 - 回滚:删掉
dxgi.dll与配置文件,重启应用即可。
8.3 数值怎么选
- 从「真实显存的一半」起步(24GB → 12GB),确认有效后逐步上调;
- 目标是:整卡峰值留 15~20% 余量、无溢出尖峰、操作无感知;
- 本案例最终选 10GB(≈卡容量的 40%)——并用你日常最重的工作流做最后验证 (AI 蒙版类操作会带来数 GB 的瞬时突发,见第 6 节的边界教训);若后台还有重显存程序,再保守一档。
09适用边界与风险
- 仅 Windows / WDDM;当前代码为 x64;
QueryVideoMemoryInfo需 Win10 1703+; - 只对「尊重预算」的应用有效——对完全无视该接口的软件等于没装;
- 对游戏 / 引擎可能改变纹理流送策略(是「降质量」不是「崩溃」); 绝不要对带反作弊的在线程序使用;
- Windows 更新后系统
dxgi.dll的导出可能变化:升级后先跑一次导出比对脚本,必要时重新构建; - 杀软可能对「应用目录里的 dxgi.dll」敏感——请自行编译、来源可信;
- 这不是官方方案:保留回滚手段,风险自担。
10常见问题
会不会让 Lightroom 变慢?
为什么不用 Windows 图形设置限制它?
能用在 Photoshop 吗?
怎么判断别的软件适不适用?
QueryVideoMemoryInfo、以及调用后行为是否变化;
不查询的应用装上也无效。
本文为个人实验记录,由AI辅助生成,请注意甄别。
与 Adobe 无关联,不构成官方支持复现风险自负修改第三方程序目录中的文件前请确保可回滚


