IE6–IE8中DOM与JS对象双向循环引用会锁死COM引用计数,导致内存无法释放,表现为页面长期运行后变卡、崩溃且刷新无效;典型场景包括DOM节点与JS对象互相赋值、事件回调闭包隐式持有DOM引用。

旧版浏览器(尤其是 IE6–IE8)中,对象循环引用引发的内存常驻问题,核心在于 COM 对象与 JavaScript 对象交叉引用,导致引用计数无法归零,垃圾回收器失效。这类问题不会报错,但页面长期运行后明显变卡、崩溃,且刷新也无法释放——这就是典型信号。
看 DOM 与 JS 对象是否“双向绑定”
这是最常见也最危险的场景。当原生 DOM 元素(如 document.getElementById 返回的对象)和 JS 对象互相持有引用时,IE 的 COM 引用计数机制就会锁死内存:
-
DOM → JS:比如
element.someObject = myObj -
JS → DOM:比如
myObj.element = element
哪怕元素已被 removeChild 或从文档移除,只要这两个引用还存在,DOM 节点及其所有子树就永远驻留在内存中。
查事件监听器是否隐式维持引用
在旧版 IE 中,使用 attachEvent 绑定事件时,若回调函数内访问了外部对象(尤其是闭包捕获的 DOM 或大对象),极易形成隐蔽循环:
- 回调函数本身被 DOM 元素强引用
- this、
that或局部变量) - container.el = div)
这种三层嵌套引用,在 IE 下极难被标记清除,需结合内存快照交叉验证。
用 IE Developer Tools 抓 Heap Snapshot
IE8+ 自带的开发者工具支持内存快照比对,是识别的关键手段:
- 先在空闲状态拍一张快照(Snapshot #1)
- 执行疑似有问题的操作(如打开弹窗、渲染列表、切换 tab)
- 再强制触发 GC(菜单 → “垃圾回收”按钮),然后拍第二张快照(Snapshot #2)
- 筛选类型为
DOMWindow、HTMLDivElement或Script Object,查看 “Retained Size” 是否异常增长 - 点击对象,看右侧 “References” 面板里是否存在跨域/跨上下文的双向路径(如
someObject → element → someObject)
观察页面卸载前是否残留全局挂载
旧版 IE 对 window.onunload 执行不严格,若在页面销毁前未手动清理,极易遗留:
- 全局变量直接引用 DOM 元素(如
window.cacheEl = document.getElementById(...)) - 定时器回调中持续访问已销毁节点(
setInterval(() => el.innerHTML = 'x', 100)) - 未解绑的
onpropertychange、onreadystatechange等老式事件
这类残留不会立即暴露,但多次跳转同一页面后,内存占用呈阶梯式上升,重启浏览器才能恢复。


















