Chrome内存快照里怎么判断是不是内存泄漏?
我在用 Chrome DevTools 的 Memory 面板拍快照,但不太会看那些 retained size 和 distance,到底怎么看才能确定是不是真的内存泄漏了?
我试过反复打开关闭一个组件,按理说应该被回收,但快照里还是能看到很多 detached DOM tree,像这样:
function createModal() {
const div = document.createElement('div');
div.innerHTML = '<button>Close</button>';
document.body.appendChild(div);
div.querySelector('button').onclick = () => {
document.body.removeChild(div);
};
}
这种写法是不是会导致闭包引用没释放?该怎么分析?
retained size 是关键,这个值表示这个对象以及它引用的所有东西总共占多少内存。distance 是到GC根的距离,距离越小越可疑,说明它很可能是泄漏链的源头。
你说的 detached DOM tree 就是典型问题。你那段代码确实有闭包泄漏:
点击关闭按钮后,div 虽然从 DOM 移除了,但 onclick 回调函数形成了一个闭包,这个闭包还持有着 div 的引用。事件处理器没清掉,对象就回收不掉。
怎么分析:
1. 在 Memory 面板拍下初始快照
2. 重复操作你的功能(比如打开关闭弹窗)十几次
3. 再拍一次快照
4. 选择第二个快照,切换到 Comparison 视图
5. 看 # Delta 列,正数的就是增长的对象
找到泄漏对象后,点进去看 Retainers 面板,一层层往上追,看是什么引用链保持着它。
修复办法:
或者更彻底的做法是用 EventListener,并且确保在组件销毁时 removeEventListener。关键就是手动断开引用,让 GC 能回收。