ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

内存泄漏的5种常见情况

内存泄漏的5种常见情况 ### 1. 全局变量引用javascript// ❌ 会泄漏function test() {user { name: 张三 }; // 没写 var/let/const变成全局变量}test();// user 永远存在无法回收// ✅ 正确function test() {let user { name: 张三 }; // 局部变量}test();// user 自动回收---### 2. 闭包持有大对象javascript// ❌ 会泄漏function outer() {let bigData new Array(1000000); // 大数组return function() {return bigData[0]; // 只取第一个元素却持有整个数组};}const fn outer();// bigData 永远不会被回收// ✅ 正确function outer() {let bigData new Array(1000000);let first bigData[0]; // 只存需要的值return function() {return first;};}---### 3. 定时器未清理javascript// ❌ 会泄漏function start() {let data { name: 测试 };setInterval(() {console.log(data.name); // data 一直被引用}, 1000);}start();// data 永远不会被回收// ✅ 正确function start() {let data { name: 测试 };const timer setInterval(() {console.log(data.name);}, 1000);// 不需要时清理clearInterval(timer);}---### 4. 事件监听器未移除javascript// ❌ 会泄漏function setup() {let data { id: 1 };document.getElementById(btn).onclick function() {console.log(data.id); // data 被引用};}setup();// 即使按钮被移除data 依然存在// ✅ 正确function setup() {let data { id: 1 };const handler function() {console.log(data.id);};const btn document.getElementById(btn);btn.addEventListener(click, handler);// 移除时清理btn.removeEventListener(click, handler);}---### 5. 缓存无限增长javascript// ❌ 会泄漏const cache [];function addData() {cache.push({ big: new Array(1000) }); // 不断累积}addData(); addData(); addData();// 数据越来越多从不清理// ✅ 正确const cache [];const MAX_SIZE 10;function addData() {if (cache.length MAX_SIZE) {cache.shift(); // 超出时移除旧的}cache.push({ big: new Array(1000) });}---## 快速总结表| 泄漏类型 | 原因 | 解决方法 ||---|---|---|| **全局变量** | 忘记 var/let/const | 使用 let/const || **闭包** | 内部函数引用外部大对象 | 只引用需要的数据 || **定时器** | 忘记 clearInterval | 不用时清理 || **事件监听** | 忘记 removeEventListener | 移除时清理 || **缓存** | 无限增长 | 设置大小限制 |##案例测试##1.闭包内部函数引用外部函数的变量内存泄露function outer() {let a 1; // a 在 outer 的作用域return function() { // 返回的内部函数return a 1; // 引用了外部变量 a → 形成了闭包};}const inner outer(); // inner 持有对 a 的引用inner(); // a 依然存在不会被回收##2.局部变量 赋值给全局变量 导致内存泄露let globalCache {}; // 全局对象function outer() {let a { cc: 3 }; // ① 堆内存创建对象globalCache.current a; // ② 全局引用指向对象} // ③ outer 执行完毕outer(); // 调用// globalCache.current ────→ { cc: 3 } ← 永远存在##3.函数参数 不会内存泄漏function outer() {let a 1; // ① outer 的局部变量 areturn function(a) { // ② 内部函数有自己的参数 a同名遮蔽return a 1; // ③ 这里的 a 是参数不是 outer 的 a};}const inner outer(1); // inner 得到内部函数inner(); // 返回 NaN因为没传参a undefined##4.函数调用 不会内存泄漏function b(a) {return a 1; // ② b 接收 a 1返回 2}function outer() {let a 1; // ① 创建局部变量 ab(a); // ② 调用 b传递 a 的值拷贝}// ③ outer 执行完毕outer(); // 调用
返回列表