- NO.
- 029
- DATE
- READ
- ~7 min
- KIND
- 案例
- STATUS
- 原文
Windows 内存释放大法:折腾半天,最后发现真正吃内存的是我自己
16GB Windows 11 + WSL2 + VMware 环境下,从 WSL、非分页池、WebView2 一路排到 Widgets、Search 和传递优化;最后 Apply/Restore 实测几乎没差,真正的大头还是 Chrome 和自己开的应用。
最近电脑经常动不动内存就往 90% 上边跑。虽然只是 16GB 吧,但是我也没开什么特别大的应用,而且更离谱的是:有时候刚开机,只开几个小的自启动应用,内存就已经七八十了。
这还怎么玩,是时候优化一下了。
先把结论放前面:这次折腾最后变成了一次失败的“内存优化”,但算是一次挺成功的排查。
我从 WSL、非分页池一路查到 WebView2,后边甚至还写了一个脚本去关 Windows Widgets、搜索里的联网内容和传递优化 P2P。脚本的 Apply / Restore 都跑通了,结果——内存基本没区别。
真正的大头其实从头到尾就写在监控输出里:Chrome、WebView2 宿主应用、ChatGPT,以及我自己开的那堆东西。
哈哈哈哈,白搞。
我的环境
机器是惠普暗影精灵 8:16GB 内存、i7-12700H、RTX 3050,原装 512GB SSD,后来又加了一块 2TB 固态。
日常环境也不算特别“轻”:
- Windows 11 宿主机;
- WSL2 Ubuntu 24.04,里面跑一些服务和自启动任务;
- VMware 里还有一台 Ubuntu 26.04;
- Chrome(无底洞);
- ChatGPT / Codex Desktop;
- 代理、坚果云、Telegram、Typora、PowerToys 等常驻应用。
所以一开始我最怀疑的其实是 WSL。
第一刀先砍 WSL:限制到 4GB
先让 Codex CLI 在 WSL 里排了一轮,没定位出什么异常,最后先做了一个比较保守的动作:给 WSL2 设个内存上限。
%userprofile%\.wslconfig:
[wsl2]
memory=4GB
processors=4
改完之后要执行:
wsl --shutdown
然后重新启动发行版才会生效。
这里注意一下:memory=4GB 才是限制 WSL2 VM 的内存上限,processors=4 是限制逻辑处理器数量,和“释放内存”不是一回事。我的数值只是自己的配置,不建议照抄。
后边真正内存吃紧的时候,vmmemWSL 的 Working Set 只有一百多 MB,所以至少在那次现场里,WSL 不是主要嫌疑人。但这不能反过来证明“限制 4GB 给我省了多少内存”——只能说当时它没在吃。
然后被 1.7GB 非分页池带跑偏了
接着我把任务管理器的进程页、内存页截图丢给 Codex Desktop。它注意到非分页缓冲池有大约 1.7GB,于是后边花了不少时间沿着这个方向查。
最后没找到持续增长,也没定位到哪个驱动在泄漏。
现在回头看,这一步最大的问题不是“1.7GB 到底正不正常”,而是只有某一个时刻的截图,没有时间序列,就很难证明它是问题来源。一个数字看起来偏大,不等于它就是导致 90% 内存占用的罪魁祸首。
于是第二天重启之后,我改成了一个笨但有效的办法:等内存真不够的时候再抓现场。
让 PowerShell 在内存见底时抓现场
最开始用的脚本会每 5 秒看一次系统可用内存,低于 1GB 时,把进程按内存排出来。
不过后来发现原版有一个口径坑:它按 PrivateMB 排序。真正要看“现在有多少东西压在物理内存里”,WorkingMB 更有参考价值,所以整理到这里我把排序改成了 Working Set:
while ($true) {
$m = Get-CimInstance Win32_PerfFormattedData_PerfOS_Memory
if ($m.AvailableMBytes -lt 1000) {
"`n$(Get-Date) Available=$($m.AvailableMBytes)MB"
Get-Process -ErrorAction SilentlyContinue |
Group-Object ProcessName |
ForEach-Object {
[pscustomobject]@{
Process = $_.Name
WorkingMB = [math]::Round(
($_.Group | Measure-Object WorkingSet64 -Sum).Sum / 1MB
)
PrivateMB = [math]::Round(
($_.Group | Measure-Object PrivateMemorySize64 -Sum).Sum / 1MB
)
}
} |
Sort-Object WorkingMB -Descending |
Select-Object -First 10 |
Format-Table -AutoSize
}
Start-Sleep 5
}
这段只是读状态,一般不需要管理员权限。
然后我把自己每天签到和常用的页面全打开,合计 28 个 Chrome 标签页。可用内存很快掉到 600~800MB 左右,现场终于抓到了。
其中一次是这样:
| Process | WorkingMB | PrivateMB |
|---|---|---|
| chrome | 7373 | 5090 |
| msedgewebview2 | 1386 | 2130 |
| ChatGPT | 1261 | 1093 |
| svchost | 997 | 605 |
| Typora | 613 | 543 |
| MsMpEng | 400 | 486 |
| Telegram | 434 | 430 |
| PowerToys.PowerLauncher | 76 | 379 |
| NutstoreClient | 227 | 366 |
这张表一下把前边很多猜测打回原形了。
尤其是 PowerToys Run:它的 PrivateMB 有 379MB,看着很吓人;但 WorkingMB 只有 76MB。所以“关掉 PowerToys Run 直接省 379MB”这种算法是不成立的。
当然我本来就几乎不用 Alt + Space,所以还是把它关了——不用的东西不常驻,总归没坏处。
WebView2 看着很大,但它不是一个软件
接下来最显眼的是 msedgewebview2。
我第一反应也是:“我什么时候装过这个?”
后来才搞明白,WebView2 是很多 Windows 组件和第三方桌面应用拿来渲染网页式界面的运行时,而且它本身就是多进程模型。任务管理器里的一堆 msedgewebview2.exe,并不代表它们都属于同一个应用。
所以这里同样不能看到:
msedgewebview2 1.3GB Working Set
就直接得出:
Windows 小组件吃了 1.3GB
完全不是一回事。
真正想知道是谁在用,可以去任务管理器“详细信息”里把“命令行”列打开,或者看父进程,把 WebView2 进程重新归因到宿主应用。
而我的这次现场已经很直白了:Chrome 7GB+、WebView2 合计约 1.3GB、ChatGPT 1.2GB。 真正的大头明明都在自己开的应用上。
但我还是不死心:Windows 自带的东西能不能再抠一点?
到这里我又盯上了两个自己基本不用的东西:
- Windows 11 Widgets / 小组件;
- Windows Search 里的 Search Highlights、网页结果。
再加上 Delivery Optimization 的 P2P,我最后还是写了一个可恢复的 PowerShell 脚本做测试。
不过经历前边那轮之后,这版就没再走“见服务就禁”的路线了。思路只有三个:
- 只改策略,不卸系统组件;
- 不禁 SysMain、DiagTrack、Remote Registry、DoSvc 这些服务;
- 修改前记录原注册表状态,恢复时按原状态回滚,而不是猜 Windows 默认值。
传递优化也只是把 DODownloadMode 调到 0,也就是关掉 P2P;没有去禁用 DoSvc。
搜索策略在不同 Windows Edition / Build 上是否真正生效也有差异,所以这次我没把它包装成什么“Win11 通用一键优化”,就当成一次自己的机器上的实验。
第一次运行甚至还先被 PowerShell 执行策略拦了:脚本没数字签名,最后是在 PowerShell 里临时用了:
Set-ExecutionPolicy -Scope Process Bypass
这个作用域只影响当前 PowerShell 进程,窗口关掉就结束。
然后 Apply 正常执行,备份也成功写到了:
C:\ProgramData\WinMemoryTrim\backup.json
实测结果:好像降了?不,没区别
这是 Apply 之后的任务管理器截图,当时显示内存大约 61%:

第一眼:“诶?是不是降下来了?”
然后我把恢复脚本也跑了一遍。之前新增的 Widgets、Search、Delivery Optimization 策略值全部按备份逻辑删掉 / 还原,再看任务管理器:

59%。
哈哈哈哈。
恢复完反而还比“优化后”低 2 个百分点。
当然,这两张截图不是严格控制变量的 benchmark:后台进程在动、Defender 在动、缓存也在动,不能拿 61% 和 59% 得出“恢复还能省内存”这种反向结论。
但它至少足够推翻我一开始那个期待:
关掉 Widgets + 搜索联网 + 几个 Windows 服务,就能稳定释放几百 MB,甚至 1~2GB。
至少在我这台机器上,没有看到这种级别的收益。 两次粗测的差异连方向都不稳定,更像正常的后台波动。
而且恢复之后,Windows 小组件重新出现在任务管理器里也就一百多 MB 的量级。和 7~8GB 的 Chrome 放在一起,优先级已经很明显了。
所以到底什么对我有用?
折腾一圈之后,真正值得做的反而很朴素:
- Chrome 开“内存节省程序”,我这种二三十个标签页的场景最有针对性;
- 不用的标签页真的关掉——我知道,但我就是做不到🤣;
- PowerToys Run 这种自己确实不用的常驻功能直接关;
- 找出到底哪些应用在养着 WebView2,没必要常驻的就退出,而不是去删 WebView2 Runtime;
- WSL / VMware 只在需要的时候开,或者给它们设合理上限;
- 如果长期就是 Chrome + WSL2 + VMware + 一堆桌面应用一起跑,16GB 本身就是紧张,32GB 才是最直接的解决方案。
Widgets、Search 联网结果这些当然也可以按个人偏好关掉,但现在我更愿意把它们叫“去掉自己不用的功能”,而不是“内存优化”。
如果真想测,至少别只看一张任务管理器
这次我的测试本身也比较粗。如果以后真要认真比较某个优化到底有没有意义,我会按这种方式做:
重启
→ 空闲几分钟
→ 固定同一批应用 / 标签页
→ 记录 Available Memory + Working Set
→ 只改一个变量
→ 再重启 / 注销
→ 重复同样负载
→ 多跑几轮再比较
最重要的是一次只改一个东西,不然最后看到数字变化,也不知道是谁造成的。
另外,凡是会改注册表、服务启动类型或者卸系统组件的“优化脚本”,恢复逻辑最好先写、先测,再谈一键执行。尤其不要写死“恢复成 Automatic”之类的默认值——用户原来是什么状态,就应该恢复成什么状态。
最后
所以这次最大的收获,不是“找到了 Windows 偷吃的 2GB 内存”,而是把一个特别容易相信的故事完整跑了一遍:
内存高
→ Windows 后台垃圾太多
→ 关几个服务 / 小组件
→ 轻松释放 1~2GB
至少在我这台机器上,这条链不成立。
真正把内存吃掉的,就是我自己开的 Chrome、WebView2 宿主应用、ChatGPT,再叠 WSL / VMware 这种使用方式。Windows 自带那些东西有的确实可以关,但别指望它们替 16GB 内存续命。
从“Windows 内存释放大法”折腾到最后,结论变成了:
少开点东西,或者加内存。
好嘛,绕了一大圈又回到第一句话了🤣。
以上,下次见。
评论
评论由 GitHub Discussions 提供。登录 GitHub 后即可评论。 前往对应 Discussion