Safari GC未运行?点击reload按钮后内存无限增长问题咨询
问题原因
这是Safari浏览器垃圾回收机制的已知缺陷,触发逻辑如下:
- 每次执行
init函数时,内部创建的DOM节点绑定了事件监听器,监听器的回调函数作为闭包,捕获了init作用域内的其他对象 - 点击reload按钮移除旧DOM节点时,Safari不会自动切断已脱离DOM树的节点和其绑定的事件监听器闭包之间的引用关系
- DOM节点和闭包形成的循环引用链会被Safari的垃圾回收器误判为仍处于活跃状态,导致整个
init函数作用域内的所有对象都无法被清理,每次重载都会叠加内存占用,最终出现无限增长的问题
可行规避方案
- 移除DOM节点前,手动调用
removeEventListener清理所有绑定的事件监听器,不要依赖浏览器自动回收 - 避免在事件回调的闭包中引用大体积对象,若有必要引用,在节点销毁前手动将对应变量赋值为
null切断引用链 - 若使用前端框架开发,优先使用框架内置的事件绑定能力,主流框架大多已经适配了Safari的这个缺陷,会在节点卸载时自动清理关联事件
内容的提问来源于stack exchange,提问作者ka8725
相关产品推荐
相关产品推荐

