如果我有A
实现接口的类I
并将其传递给期望接口的某个地方I
,例如一个线程,这会阻止 GC 垃圾收集类的实例A
吗?我认为是的,但我应该如何解决这个问题?假设创建公共静态内部类?
4 回答
对象的引用类型在这里无关紧要。它可能与对象的类型相同,它的超类型或接口。根本没关系。
重要的是对象是否可以从根上下文访问。直到一个对象对它有一个有效的引用(不管它的引用类型),它都不会被垃圾收集。
事实上,该对象甚至可能没有直接引用它。如果它可以从根上下文间接访问(从 GC 根的树遍历),它仍然不符合 GC 的条件,如下所述。
什么是根上下文?
您的程序在根目录处创建的所有对象(即直接喜欢的对象)Parent p = new Parent();
都被调用GC Roots
,它们共同构成根上下文。没有一个 GC Root 有资格进行垃圾收集。现在,如果您创建一个新Child
对象,例如
p.setChild(new Child());
然后Child
对象(虽然不是 GC Root)可以通过Parent
p 从根上下文访问,因此不符合垃圾收集条件。现在,如果您将当前孩子替换为
p.setChild(new Child()); // old child replaced
旧的子对象变成孤儿(不再可以从根上下文访问),因此会被垃圾收集。因此,您可以看到引用类型与对象的垃圾回收无关。
而且,为了完整地说明这个主题:孤立对象的孤岛(尽管它们可能持有彼此的引用)仍然会被垃圾收集,因为它们无法从根上下文中访问。
Objects
变得有资格进行垃圾收集..不是引用。所以你可以说如果一个对象references
都是terminated
. .
不,它不会垃圾收集实例,因为对对象的引用仍然存在于线程堆栈中。
我通过将 WeakReference 保存到接口实现来解决所有问题。