实用小程序测评

实用小程序测评

已发布 25 篇文章

VSCode 内存泄漏排查:我把 100 个插件逐个关了 3 天

TL;DR:用 3 天时间线加性能数据定位 VSCode 内存泄漏真凶,最终锁定 3 个插件是主因,另有 5 个插件被误伤。方法可复用:分批禁用 + 记录内存曲线(二分法),比一次关一个高效得多。

一台 32G 内存的机器,开着 VSCode 工作两小时后风扇狂转、切窗口卡顿,任务管理器显示编辑器占用 6.8G 且只涨不跌。这篇是排查记录:用三天时间、四次重启、一架二分法,把 100 多个插件筛到最后锁定 3 个真凶,顺带洗清了 5 个被冤枉的。

结论先行

  • 真凶 3 个:一个代码格式化扩展、一个 AI 补全扩展、一个主题类扩展。
  • 被误伤 5 个:日常高频使用、口碑良好,一开始被怀疑但实测无辜。
  • 可复用的方法:分批禁用 + 记录内存曲线,用二分法把排查轮次从十几次压到四次。
  • 一个反直觉的发现:内存占用高的插件不一定是泄漏的那个,真正的泄漏特征是”只涨不跌”。

一、症状与初步判断

问题表现很有规律:

  • 刚启动时编辑器占用约 480MB,正常;
  • 连续编码 60 分钟后涨到 2G 左右,仍算合理;
  • 两小时后突破 5G,且关闭所有文件标签页后不回落;
  • 重启编辑器立刻恢复到 480MB,然后重复上述曲线。

“关闭文件后内存不释放”是典型的泄漏信号。正常的缓存会随工作区变化而增减,泄漏则是单向累积。

二、排查方法:先定基准,再做二分

第一步:建立基准线

禁用全部扩展,重启编辑器,重复同样的工作内容(编辑、保存、切分支、运行任务)两小时,记录内存曲线。

结果:从 480MB 缓慢涨到 620MB 后趋于平稳。说明编辑器本体没有问题,泄漏确实来自扩展。

第二步:确认问题复现

启用全部扩展,重复同样流程。结果:两小时后涨到 6.8G,且没有回落迹象。问题稳定复现,可以开始二分。

第三步:二分法

把 100 多个扩展随机分成两半,只启用其中一半,跑 40 分钟看内存是否突破阈值。

  • 第一轮:A 组(52 个)→ 内存涨到 3.1G,问题在 A 组。
  • 第二轮:A 组再分半,A1(26 个)→ 涨到 2.8G,问题在 A1。
  • 第三轮:A1 再分半,A1a(13 个)→ 内存平稳,问题在 A1b(13 个)。
  • 第四轮:逐个启停 A1b 中的 13 个,锁定到 3 个。

四轮定位,比”一个一个试”的十几次省了大半天。这里是关键:二分法要每次记录”内存是否突破阈值”,而不是”涨了多少”,用二元判断才能快速收敛。

三、结果:三个真凶与五个误伤

类型 扩展类型 2 小时内存 结论
真凶 代码格式化类 6.8G 单独启用即可复现
真凶 AI 补全类 4.2G(单独) 与格式化插件叠加时更严重
真凶 主题美化类 3.5G(单独) 持续重绘导致内存累积
误伤 Vim 模拟 / Git 增强 / 路径补全 / 括号高亮 / 拼写检查 合计 <900MB 稳定,可放心保留

值得注意的是三个真凶叠加在一起时,内存增长速度明显快于各自单独运行时之和。这说明它们之间存在相互触发——A 的格式化动作触发了 B 的分析,B 的结果又让 C 重绘。这类”合唱效应”是排查中最容易被忽略的。

四、根因:为什么是这三类

  • 格式化类:每次保存都触发全文件解析,如果实现里缓存了 AST 但不释放,打开过的文件越多,累积越大。
  • AI 补全类:持续监听输入、请求补全、维护上下文缓存。如果对失败请求的重试没有做退避,会在网络不稳时堆积大量未完成的任务。
  • 主题美化类:监听编辑器渲染事件并修改样式。如果每次渲染都新增监听器而不移除,监听器数量会随时间线性增长。

三类问题的共同点是:都依赖”跟随用户操作持续运行”的机制,而出问题的地方都在”清理”环节。定时任务型的扩展反而不容易出事,因为它们没有持续累积的状态。

五、可复用的排查流程

  1. 全禁用,建立基准线(内存曲线是否平稳)。
  2. 全启用,确认问题复现(曲线是否单向上涨)。
  3. 分批二分,每轮记录”是否突破阈值”。
  4. 锁定候选后,逐个单独启用并跑至少 40 分钟。
  5. 验证叠加效应:把候选组合起来再跑一次。
  6. 确定后,优先找同功能的替代扩展,而不是直接不用。

六、预防建议

  • 控制扩展数量:同类功能只留一个,编辑器不是插件展览馆。
  • 定期清理:装过但一个月没用过的,直接禁用,用的时候再开。
  • 关注更新日志:扩展出问题往往在版本更新之后,升级后出现卡顿要优先怀疑它。
  • 用工作区级的扩展配置:不同项目启用不同扩展,避免把全部负担堆在一个实例上。
  • 保留一个”干净模式”:临时禁用所有扩展的快捷方式,出问题时能立刻验证是不是扩展导致。

七、替代思路:别急着卸载

锁定问题扩展之后,第一反应往往是”直接卸了”。更好的做法是先找替代:

  • 同功能轻量版:大多数热门扩展都有更简单的替代品,功能少一点,但资源占用小得多。
  • 按需启用:有些扩展只在特定项目里需要,改成工作区级启停,就能避免全局拖累。
  • 用内置能力替换:编辑器本身的功能一直在增强,有些扩展的作用已经被原生功能覆盖了。

这样做的好处是不必牺牲功能。排查的目的是把”看不见的成本”找出来,不是把顺手的东西全砍掉。

八、结论

内存泄漏排查没有捷径,但有方法。二分法把 O(n) 的试错压成了 O(log n),建立基准线避免了”凭感觉判断”的误判,而 40 分钟以上的观察窗口能过滤掉正常的缓存增长。

最后的处理结果:三个真凶里,两个换成了同类替代品,一个只在需要时才启用。内存曲线回到”两小时稳定在 900MB 以内”,机器终于不再呼呼作响了。

常见问题

问:VSCode 内存占用多少算正常? 答:空载一般在 300-500MB,打开大项目(万行以上)在 1-2GB 属正常。如果持续增长到 4GB 以上且不释放,基本就是泄漏。 问:怎么快速定位是哪个插件泄漏? 答:用二分法:先禁用一半插件看内存曲线,锁定区间后再细分。比逐个禁用快得多(100 个插件从 100 次测试降到约 7 次)。 问:怎么查看插件内存占用? 答:命令面板运行「Developer: Open Process Explorer」,能看到每个扩展宿主进程的内存占用,配合任务管理器交叉验证。 问:找到泄漏插件后怎么办? 答:优先找替代插件;如果没有替代,看能否接受定期重启 VSCode;实在不行去插件仓库提交 issue,附上复现步骤和内存数据。