支配者¶
本文介绍了可达性、浅层与保留大小以及支配者的概念,这些概念适用于 JavaScript 等垃圾收集语言。
这些概念在内存分析中很重要,因为对象本身可能很小,但可能持有对其他更大对象的引用,并且通过这样做会阻止垃圾回收器释放额外的内存。
您可以使用内存工具中的支配者视图查看页面中的支配者。
在像 JavaScript 这样的垃圾收集语言中,程序员通常不必担心释放内存。他们可以创建和使用对象,当不再需要对象时,运行时负责清理并释放对象占用的内存。
可达性¶
在现代 JavaScript 实现中,运行时根据可达性来决定对象是否不再需要。在这个系统中,堆表示为一个或多个图。图中的每个节点表示一个对象,节点之间的每个连接(边)表示从一个对象到另一个对象的引用。图从一个根节点开始,在这些图中用“R”表示。
在垃圾回收期间,运行时遍历图,从根节点开始,并标记它找到的每个对象。它找不到的任何对象都是不可达的,并且可以被释放。
因此,当一个对象变得不可达(例如,因为它只被一个超出作用域的单个局部变量引用)时,它引用的任何对象也变得不可达,只要没有其他对象引用它们。
相反,这意味着只要其他可达对象持有对它们的引用,对象就会保持活动状态。
浅层和保留大小¶
这产生了两种看待对象大小的方法之间的区别
浅层大小:对象本身的大小
保留大小:对象本身的大小,加上此对象保持活动状态的其他对象的大小
通常,对象将具有较小的浅层大小,但通过它们包含的对其他对象的引用,具有更大的保留大小。保留大小是分析内存使用情况中的一个重要概念,因为它回答了“如果此对象不再存在,将释放多少内存?”的问题。
支配者¶
一个相关的概念是支配者。如果从根节点到 A 的每条路径都经过 B,则称节点 B 支配节点 A。
如果 A 的任何支配者被释放,则节点 A 本身就会有资格进行垃圾回收。
如果节点 B 支配节点 A,但不支配 A 的任何其他支配者,则 B 是 A 的直接支配者。
这里有一个细微差别,如果对象 A 被另外两个不相关的对象 B 和 C 引用,则这两个对象都不是它的支配者,因为您可以从图中删除 B 或 C,而 A 仍然会被其其他引用者保留。相反,A 的直接支配者将是它的第一个公共祖先。