JavaScript 内存管理
本节目标:理解垃圾回收的可达性原则,并识别常见内存泄漏来源。
生命周期与可达性
对象创建后占用内存。现代引擎会自动回收无法从程序可达根(例如当前执行栈和全局对象)访问的对象。开发者通常不手动释放普通对象内存,但仍需管理事件监听器、定时器、订阅和外部资源。
常见泄漏来源
- 长期存活的全局缓存无限增长。
- 已移除的 DOM 节点仍被闭包或集合引用。
- 页面组件卸载后,事件监听器或定时器仍在运行。
- Promise、订阅或 Worker 生命周期未结束。
js
const controller = new AbortController();
window.addEventListener("resize", onResize, { signal: controller.signal });
// 页面组件销毁时
controller.abort();及时结束不再需要的任务或解除引用。WeakMap 和 WeakSet 适合附加不会阻止对象回收的元数据,但不可枚举,不能用来管理确定性清理。
诊断
若页面持续变慢或内存占用不断增长,使用浏览器开发者工具的内存快照和分配时间线,比较对象数量与保留路径。不要依赖非标准的强制垃圾回收调用作为产品逻辑。
小结与练习
- 垃圾回收依据可达性自动回收对象。
- 监听器、计时器、缓存和外部任务的生命周期仍需主动管理。
- 用快照与保留路径诊断泄漏,而不是猜测某个变量占内存。
练习:为一个动态创建并销毁的 DOM 控件设计初始化与清理函数,确保事件监听器被移除。