JavaScript 中的内存管理
文章类型:Javascript
发布者:hp
发布时间:2025-04-21
JavaScript 内存管理尤其是在构建复杂应用时。如果内存管理不当,可能会导致内存泄漏、性能下降甚至应用崩溃,那么怎么处理呢?
内存管理机制主要围绕自动内存分配和垃圾回收两大核心
(1)栈内存(Stack)
存储基本数据类型(如 number、string、boolean 等)和函数调用上下文(如局部变量、参数等)
系统自动分配和释放,遵循后进先出(LIFO)原则,效率高但容量有限
(2)堆内存(Heap)
存储引用类型数据(如对象、数组、函数等),由 JavaScript 引擎动态分配
变量通过内存地址引用堆中的数据,需依赖垃圾回收机制释放
(1)标记-清除(Mark and Sweep)
标记阶段:从根对象(如 window 或全局对象)出发,递归标记所有可达对象。
清除阶段:回收未被标记的对象内存。该算法能有效处理循环引用问题
(2)引用计数
通过统计对象的引用次数决定是否回收,但无法处理循环引用(如两个对象互相引用)
1:全局变量未释放
function leak() {
leakedVar = '这是一个全局变量'; // 意外的全局变量
}
2:未清理的 DOM 引用与事件监听
let element = document.getElementById('myElement');
document.body.removeChild(element); // DOM 元素被移除
console.log(element); // 仍然保留对 DOM 元素的引用
3:闭包长期占用内存
function createClosure() {
let largeData = new Array(1000000).fill('data');
return function() {
console.log(largeData[0]); // 闭包引用了 largeData
};
}
let closure = createClosure();
4:未清除的定时器或回调
let data = fetchData();
setInterval(() => {
processData(data);
}, 1000);
5:未释放的缓存
let cache = {};
function addToCache(key, value) {
cache[key] = value;
}
1:使用弱引用:WeakMap 和 WeakSet
let weakMap = new WeakMap();
let key = {};
weakMap.set(key, 'value');
key = null; // key 被回收,weakMap 中的条目也会被清除
2:及时清理资源
let timer = setInterval(() => {}, 1000);
clearInterval(timer); // 清除定时器
element.addEventListener('click', handler);
element.removeEventListener('click', handler); // 移除事件监听器
3:优化数据结构
4:使用工具检测内存泄漏
5:分块处理大数据
6:避免频发创建对象