JavaScript 内存泄露
JS 内存泄露指的是程序中不再使用的内存没有被及时释放,导致这部分内存被持续占用,最终使程序占用内存越来越多,甚至引发性能下降、页面卡顿、崩溃等问题。
要点速览
shell
# 内存泄漏的场景
- 意外的全局变量:函数内未声明的变量会成为全局对象(如 window)的属性,不会被垃圾回收机制回收
- 意外的函数闭包:闭包长期持有外部函数的变量引用,导致这些变量无法被回收
- 未清理的全局事件:window.addEventListener
- 未清理的定时器:忘记清除的定时器或事件监听器会导致内存泄露
- 未清理 DOM 引用
# 解决方式
- 意外的全局变量:必须使用关键词声明变量,全局变量如果不使用可以赋值为 null
- 意外的函数闭包:讲闭包函数的引用变量赋值为 null
- 未清理的全局事件:window.removeEventListener
- 未清理的定时器:clearInterval(timer)
- 未清理 DOM 引用:除非 remove dom 节点,否则无法清除如何检测内存泄露?
shell
# 方案一:使用 chrome 浏览器检测
F12,点击 performance 性能分析 --- 勾选 memory 和 web vitals --- 点击黑圆点 ---等待程序执行完 --- 点击关闭 -- 观察 HEAP 线内存变化
内存泄漏:线不断上升
正常:内存不断升降
#方案二:使用 performance.memory API 结合 定时器监控
# 使用Performance API监控内存
if (performance.memory) {
console.log(`已使用堆大小: ${performance.memory.usedJSHeapSize / 1048576} MB`);
console.log(`堆大小限制: ${performance.memory.jsHeapSizeLimit / 1048576} MB`);
}
# 定期记录内存使用情况
setInterval(() => {
if (performance.memory) {
console.log(`已使用堆大小: ${performance.memory.usedJSHeapSize / 1048576} MB`);
}
}, 5000);拓展
shell
- 在 vue 和 react 的组件卸载生命周期中,处理内存泄露:清理定时器,清理全局事件等
- 由于垃圾回收机制导致,全局变量永久有效不会被垃圾回收,除非赋值为 null