浏览器的垃圾回收机制是什么
|
zhenglin
2026年2月6日 15:32
本文热度 89
|
浏览器的垃圾回收(Garbage Collection,GC)机制是JavaScript引擎自动管理内存的核心机制,用于识别和回收不再使用的内存空间,防止内存泄漏。
一、垃圾回收的基本原理
1. 核心概念
2. 根对象(Roots)
全局对象(window/global)
当前函数的局部变量和参数
嵌套调用链上的其他函数的变量
DOM元素引用
其他全局对象
二、主要的垃圾回收算法
标记-清除算法(Mark-and-Sweep) (最常用)
// 示例:对象引用关系
let obj1 = { name: 'obj1' }; // 可达
let obj2 = obj1; // 可达
obj1 = null; // obj2仍然可达
// obj2 = null; // 如果取消注释,对象变为不可达
过程:
标记阶段:从根对象开始,标记所有可达对象
清除阶段:遍历堆内存,清除未标记的对象
2. 引用计数算法(Reference Counting) (逐渐被淘汰)
// 问题:循环引用
function problem() {
let objA = {}; // objA引用计数:1
let objB = {}; // objB引用计数:1
objA.ref = objB; // objB引用计数:2
objB.ref = objA; // objA引用计数:2
// 函数结束,objA和objB局部引用消失
// objA引用计数:1,objB引用计数:1
// 但两者都无法被访问,却无法回收 - 内存泄漏!
}
三、现代浏览器的优化策略
1. 分代回收(Generational Collection)
2. 增量回收(Incremental Collection)
将完整的GC过程分成多个小步骤
与JavaScript执行交替进行
减少单次GC的停顿时间
3. 空闲时间回收(Idle-time Collection)
四、V8引擎的垃圾回收(以Chrome为例)
1. 新生代回收:Scavenge算法
// 新生代空间(通常1-8MB)
// 对象晋升条件:
// 1. 经历过一次Scavenge回收
// 2. To空间使用超过25%
// 满足任一条件则晋升到老生代
2. 老生代回收:三色标记法
白色:未被访问的对象(待回收)
灰色:已被访问,但子引用未检查
黑色:已被访问,且子引用已检查
3. 并行和并发回收
五、内存泄漏常见场景及避免方法
1. 意外的全局变量
代码高亮:
// ❌ 错误:创建了全局变量
function leak() {
leaked = 'I am global'; // 没有var/let/const
this.globalVar = 'oops'; // 非严格模式下,this指向window
}
// ✅ 正确
function safe() {
'use strict';
let local = 'I am local';
}
2. 遗忘的定时器和回调
// ❌ 可能泄漏
let data = getHugeData();
setInterval(() => {
const node = document.getElementById('node');
if (node) {
node.innerHTML = JSON.stringify(data); // data被闭包引用
}
}, 1000);
// ✅ 及时清理
const timer = setInterval(() => { /* ... */ }, 1000);
clearInterval(timer); // 不需要时清理
3. DOM引用
// ❌ 泄漏
let elements = {
button: document.getElementById('button'),
image: document.getElementById('image')
};
// 即使从DOM移除,JS引用仍然存在
document.body.removeChild(document.getElementById('button'));
// ✅ 清理引用
elements.button = null;
4. 闭包
// ❌ 不当使用闭包
function outer() {
let largeArray = new Array(1000000).fill('*');
return function inner() {
console.log('hello'); // 引用了largeArray
};
}
// ✅ 适当释放
function outer() {
let largeArray = new Array(1000000).fill('*');
// 使用后置null
let result = process(largeArray);
largeArray = null; // 帮助GC
return result;
}
六、开发者工具中的内存分析
1. Chrome DevTools Memory工具
2. 性能监控
代码高亮:
// 监测内存使用
setInterval(() => {
const memory = performance.memory;
console.log({
usedJSHeapSize: memory.usedJSHeapSize / 1048576 + 'MB',
totalJSHeapSize: memory.totalJSHeapSize / 1048576 + 'MB',
jsHeapSizeLimit: memory.jsHeapSizeLimit / 1048576 + 'MB'
});
}, 5000);
七、最佳实践
八、不同浏览器的差异

浏览器的垃圾回收机制是不断优化的过程,现代浏览器都在努力减少GC暂停时间,提高应用性能。作为开发者,理解这些原理有助于编写更高效、更少内存泄漏的代码。
参考文章:原文链接
该文章在 2026/2/6 15:32:41 编辑过