应使用Developer: Open Process Explorer展开extensionHost节点并按Memory列排序,重点关注空闲时RSS持续>250MB的插件;区分瞬时峰值与驻留占用,禁用后须执行Developer: Restart Extension Host释放内存。

VSCode插件本身的内存占用问题,不是“调试时看变量”那种粒度,而是Extension Host进程级泄漏——不查快照、不看RSS、不关监听器,光调代码没用。
怎么快速定位哪个插件在吃内存
别翻任务管理器,直接进 VSCode 内置进程视图:Developer: Open Process Explorer。展开 extensionHost 节点,按 Memory 列排序,一眼就能看到哪些插件 RSS 长期卡在 300MB+ 不降。注意区分瞬时峰值(比如格式化大文件时 prettier 暴涨)和空闲驻留(所有文件关闭后仍 >250MB),后者才是真泄漏。
- 右键可疑插件 →
Developer: Toggle Developer Tools→ Memory 面板 →Take heap snapshot,对比两次快照中Closure、Listener、TextModel实例增长量 - 禁用插件后必须执行
Developer: Restart Extension Host,否则旧进程还在跑,内存不会释放 - 某些插件(如 Copilot、Remote-SSH)即使禁用也会残留子进程,需终端执行
ps aux | grep -i "copilot\|remote"+kill -9 [PID]
为什么 GitLens / ESLint / Prettier 容易爆内存
不是它们代码烂,是默认行为太“勤快”,在你不注意时疯狂创建对象并长期持有:
-
GitLens默认开启全仓库历史扫描 + 行级 blame + codeLens 注入,大项目下每行都挂 DOM 节点;关掉gitlens.codeLens.enabled和gitlens.hovers.enabled可降 30%–50% 内存 -
ESLint全量校验时可能占 800MB+;设"eslint.run": "onType"并精简"eslint.probe"(只留["javascript", "typescript"]) -
Prettier在保存瞬间触发全文件解析;换成prettierd(独立服务)或关掉prettier.requireConfig避免反复加载配置
自己写插件时必须加的内存防护措施
插件运行在 Node.js/V8 环境,但没有浏览器刷新重置机制,未清理的引用会持续累积:
- 避免在
activate()里require大型依赖(如acorn),改用import()动态加载,且只在需要时触发 - 缓存数据必须带 TTL 或 LRU 策略,例如用
lru-cache替代Map,并设maxSize: 100 - 调试阶段加
console.log(`[MEM] ${process.memoryUsage().heapUsed / 1024 / 1024} MB`)打点,观察每次操作后增量是否回落 - 所有事件监听器(如
vscode.workspace.onDidChangeTextDocument)必须在deactivate()中显式注销
files.watcherExclude 不配等于白优化
VSCode 默认递归监听整个工作区,遇到 node_modules(几万小文件)、.git、dist 时,内核级 inotify 句柄持续增长且几乎不回收——这是最隐蔽、最顽固的内存爬升来源。
- 必须在项目根目录的
.vscode/settings.json中添加: "files.watcherExclude": { "**/node_modules/**": true, "**/.git/**": true, "**/dist/**": true, "**/build/**": true }-
**/是关键,单星号*/或漏掉斜杠会导致子目录照样被扫 - 改完必须关闭并重新打开工作区,仅刷新窗口无效
真正难的不是拍快照,而是判断“谁该持有这个对象”。一个没注销的 onDidChangeConfiguration 监听器,可能让整个插件配置对象图永远无法被 GC——这种引用链藏在 Retainers 树最深处,得一层层点进去看顶层保留者。


















