内存泄漏
- 内存泄漏: 指的是程序中不再需要使用的内存,由于某些原因未被释放,导致内存占用持续增加的现象。如果内存泄漏累积过多,可能会导致内存溢出。
- 内存溢出: 指的是程序在申请内存时,没有足够的内存空间供其使用。
造成内存泄露的场景
- 意外的全局变量: 未声明的变量会被挂在到全局对象上,若未手动清除,会一直占用内存。
- 闭包引用未释放: 闭包长期持有外部函数变量的引用,闭包本身未被销毁时,变量无法被回收。
- DOM引用残留: 删除DOM元素后,若JS中仍保留对该元素的引用,无法回收其内存。
- 定时器/事件监听未清除: 不再使用的定时器或事件监听未被移除。会导致回调函数及内部引用的资源持续占用内存。
如何避免内存泄漏
核心就是及时释放不再使用的变量、定时器、事件监听和DOM引用,让JS的垃圾回收机制能正常回收内存。
如何排查内存泄漏
- 初步定位:观察内存趋势
- 打开浏览器开发者工具,切换到
Performance
或Memory
面板。 - 录制操作流程,重复触发可能导致内存泄漏的操作,结束录制后观察
Memory曲线
。 - 若操作后内存持续上升且不回落,大概率存在内存泄露问题。
- 打开浏览器开发者工具,切换到
- 详细分析:使用
Memory
面板- 堆快照(Heap Snapshot)对比
- 操作前录制一次堆快照(点击“拍摄快照”)。
- 重复触发可能导致内存泄漏的操作。
- 操作后再录制一次堆快照。
- 对比两次快照
- 在快照列表中选择“比较”,筛选“Retained Size”
- 重点关注DOM节点、闭包、数组、对象等异常增长的类型。
- 堆快照(Heap Snapshot)对比
- 定位具体代码:分析保留引用
- 在堆快照中,选中疑似泄露的对象,查看“保留器”面板,可追溯到引用该对象的变量或函数,顺藤摸瓜找到未被释放的引用链。