JavaScript 内存泄漏 - DOM 节点和后代上的垃圾收集

JavaScript Memory Leak - Garbage Collection on DOM Nodes and descendants

在现代浏览器中,DOM 节点会被垃圾收集器从内存中删除,前提是它们没有指向它们的引用(事件侦听器的特殊情况*)

我正在寻找有关 DOM 后代节点的一些说明。我假设后代关系是单向父->子。因此,如果父节点未附加到 DOM 并且没有引用,它将被收集,并且您将获得子元素的多米诺骨牌效应。这是正确的吗?

或者是否需要遍历节点并分离所有节点?

I assume that descendant relations are one-way parent->child.

不,这些关系是 bi-directional。

但这对垃圾收集器来说并不重要(至少不是 mark-sweep 那种),因为垃圾收集器只关心可达性,而不关心 object 的连通性。 如果使用 reference-counting 你需要一个循环收集器来检测这种情况,但是整个子树仍然可以在不首先断开 children 的情况下收集。

Or is it necessary to walk the Nodes and detach all of them?

没有必要,没有。除非您打算保留对某些后代节点的引用,但仍希望收集断开连接的树的其他部分。

Can I ask if this applies to eventListeners with anonymous functions referencing the nodes

如果匿名函数在其范围链中有 dom 节点本身(或另一个 object 持有 dom 节点)那么它取决于是否有其他东西持有该函数实例.

更一般地说:任何 object 有资格进行垃圾收集除非它可以从 GC 根访问。

在第一个近似值中,浏览器中的主 GC 根是 global/window object。如果 window object 消失,其他一切都会消失。

从 GC 根开始的路径可能很长很复杂,因此在某些情况下必须仔细考虑它们。 DOM 节点引用它们的回调函数,这些回调函数引用它们的范围链,这些范围链可以引用其他 dom 节点等等。