假设我有 2 个对象 - 对象 A 和对象 B。对象 A 引用对象 B,对象 B 引用对象 A。
- 如果 Object A 和 Object B 都超出了代码的引用 - 垃圾收集器如何知道它可以被收集。
- 垃圾收集器如何推断任何对象超出范围/准备好进行垃圾收集?
- 如果对象 A 不是我们的代码的引用,但仍然可以是独立的,那该怎么办。例如,如果它是一个 Form 类,那么即使对象 A 被重新初始化为一个新实例或指定为空,它也可以自行运行。
假设我有 2 个对象 - 对象 A 和对象 B。对象 A 引用对象 B,对象 B 引用对象 A。
GC 不会选择一个对象并查看是否有任何引用它;如果确实如此,请保留它。GC 有一个它知道是“活着”的每个对象的集合。这个集合一开始是所有静态变量、堆栈上的所有变量以及其他一些特殊情况。然后它遍历每个“活动”对象并查看它们引用的对象。每个被引用的对象本身都被标记为“活动的”,因为这意味着它可以被另一个活动的对象以某种方式访问。它重复这个过程,直到没有发现新的对象。任何未被标记为活动的东西都被认为是无法访问的。如您所知,由于您从未检查过任何给定的“死”对象引用了什么,因此是否存在循环引用无关紧要。
见#1。
好吧,在大多数情况下,它实际上是在某个地方引用的;例如,在表单的情况下,您Application.OpenForms
引用了任何打开的表单。诸如此类的对象通常存在类似的构造。在极少数情况下,诸如计时器之类的对象会被 GC 明确告知不要被收集。这种情况非常罕见,您通常无需担心。
垃圾收集器会查看活动引用,并且可以收集从那里找不到的任何内容。这样,两个对象相互引用并不重要,因为这两个引用都是非活动的。
见 1。
表单是一个组件,因此通过注册为一个组件来保持活动状态。一旦初始化,应用程序本身就会保持活动状态,直到表单被释放。拥有一个引用表单的变量,然后将变量设置为 null 只会更改引用,它不会对对象本身做任何事情。