一、垃圾回收机制核心原理
- 引用计数(Reference Counting):对象被引用时计数+1,无引用时计数-1,计数为0时回收。缺点:无法处理循环引用。
- 标记清除(Mark and Sweep):从根对象(如全局对象)开始,标记所有可达对象,未标记对象被回收。优点:处理循环引用。
- 标记整理(Mark and Compact):在标记清除后,压缩内存碎片,提升内存利用率。
- 分代收集(Generational GC):将对象分为年轻代和老年代,年轻代对象频繁回收,老年代对象长期存活。
二、垃圾回收触发时机
- 内存不足:当内存使用率超过阈值时触发。
- 对象分配:频繁创建对象时触发。
- 事件触发:如DOM操作、定时器等。
三、优化策略
3.1 减少对象创建
// ❌ 低效:频繁创建临时对象 for (let i = 0; i < 1000; i++) { const obj = {}; // 每次循环创建新对象 } // ✅ 高效:重用对象 const obj = {}; for (let i = 0; i < 1000; i++) { obj.key = i; // 重用对象 }3.2 避免循环引用
// ❌ 低效:循环引用 function createCycle() { const a = {}; const b = {}; a.ref = b; b.ref = a; // 循环引用导致内存泄漏 } // ✅ 高效:手动解除引用 function createCycle() { const a = {}; const b = {}; a.ref = b; b.ref = a; // 手动解除引用 a.ref = null; b.ref = null; }3.3 使用WeakMap
// ✅ 高效:避免强引用 const cache = new WeakMap(); function getObject(key) { if (!cache.has(key)) { cache.set(key, new ExpensiveObject()); } return cache.get(key); }四、高级优化技巧
4.1 内存池(Object Pool)
// ✅ 高效:对象池 class ObjectPool { constructor() { this.pool = []; } getObject() { return this.pool.length ? this.pool.pop() : new ExpensiveObject(); } release(obj) { this.pool.push(obj); } } const pool = new ObjectPool(); const obj = pool.getObject(); // 使用后归还 pool.release(obj);4.2 使用原生方法
// ✅ 高效:原生方法 const arr = []; arr.push(1, 2, 3); // 原生方法优化五、性能检测工具
5.1 Chrome DevTools Memory面板
- 打开DevTools (F12)
- 切换到"Memory"标签
- 点击"Take Heap Snapshot"分析内存使用
- 查看"Retainers"树图追踪引用链
5.2 性能API
// 测量内存分配 const start = performance.memory.usedJSHeapSize; // 执行代码 const end = performance.memory.usedJSHeapSize; console.log(`Memory usage: ${end - start} bytes`);六、实战案例分析
案例1:对象池优化
// ✅ 高效:对象池 class Connection { constructor() { this.id = Math.random(); } } const pool = new ObjectPool(); function getConnection() { return pool.getObject(); } function releaseConnection(conn) { pool.release(conn); }案例2:避免循环引用
// ✅ 高效:手动解除引用 function createNode() { const node = { children: [] }; node.parent = node; // 循环引用 return node; } function cleanup(node) { node.parent = null; // 手动解除 node.children.forEach(cleanup); }通过实施这些优化策略,可以显著提升JavaScript应用的内存管理效率,特别是在处理大量对象操作时。记住,性能优化是一个持续的过程,需要不断测试和调整以获得最佳效果。