Java 如果有人将对象的引用作为接口,GC会收集该对象吗?
如果我有一个类Java 如果有人将对象的引用作为接口,GC会收集该对象吗?,java,garbage-collection,Java,Garbage Collection,如果我有一个类A,它实现了接口I,并将它传递到需要接口I的某个地方,例如传递到一个线程,这会防止GC对类A进行垃圾收集吗?我想是的,但我该怎么解决呢?假设创建公共静态内部类?否,它不会对实例进行垃圾收集,因为线程堆栈中仍然存在对该对象的引用 不,它不会对实例进行垃圾收集,因为线程堆栈中仍然存在对该对象的引用 这里对对象的引用类型无关紧要。它可以与对象的类型、其超级类型或接口相同。没关系 重要的是对象是否可以从根上下文访问。直到一个对象有一个对它的有效引用(不管它的引用类型如何),它才会被垃圾收集
A
,它实现了接口I
,并将它传递到需要接口I
的某个地方,例如传递到一个线程,这会防止GC对类A
进行垃圾收集吗?我想是的,但我该怎么解决呢?假设创建公共静态内部类?否,它不会对实例进行垃圾收集,因为线程堆栈中仍然存在对该对象的引用 不,它不会对实例进行垃圾收集,因为线程堆栈中仍然存在对该对象的引用 这里对对象的引用类型无关紧要。它可以与对象的类型、其超级类型或接口相同。没关系
重要的是对象是否可以从根上下文访问。直到一个对象有一个对它的有效引用(不管它的引用类型如何),它才会被垃圾收集
事实上,对象可能不甚至与它有直接的引用。如下文所述,如果可以从根上下文间接访问(从GC根遍历树),那么它仍然不符合GC的条件
什么是根上下文?
程序在根目录下创建的所有对象,即直接像Parent p=new Parent()代码>被称为GC根
,它们共同构成根上下文。没有一个GC根符合垃圾收集的条件。现在,如果您创建一个新的子对象
p.setChild(new Child());
然后,子对象(虽然不是GC根)可以通过父对象从根上下文访问,因此不符合垃圾收集的条件。现在,如果将当前子对象替换为
p.setChild(new Child()); // old child replaced
旧的子对象成为孤立对象(无法再从根上下文访问),因此会被垃圾收集。因此,您可以看到引用类型与对象的垃圾收集无关
而且,为了完成这个主题:孤立的对象的孤岛(尽管它们可能彼此拥有引用)仍然会被垃圾收集,因为它们无法从根上下文访问。这里对对象的引用类型无关紧要。它可以与对象的类型、其超级类型或接口相同。没关系
重要的是对象是否可以从根上下文访问。直到一个对象有一个对它的有效引用(不管它的引用类型如何),它才会被垃圾收集
事实上,对象可能不甚至与它有直接的引用。如下文所述,如果可以从根上下文间接访问(从GC根遍历树),那么它仍然不符合GC的条件
什么是根上下文?
程序在根目录下创建的所有对象,即直接像Parent p=new Parent()代码>被称为GC根
,它们共同构成根上下文。没有一个GC根符合垃圾收集的条件。现在,如果您创建一个新的子对象
p.setChild(new Child());
然后,子对象(虽然不是GC根)可以通过父对象从根上下文访问,因此不符合垃圾收集的条件。现在,如果将当前子对象替换为
p.setChild(new Child()); // old child replaced
旧的子对象成为孤立对象(无法再从根上下文访问),因此会被垃圾收集。因此,您可以看到引用类型与对象的垃圾收集无关
并且,为了完成这个主题:孤立的对象的孤岛(尽管它们可能相互引用)由于无法从根上下文访问对象,因此仍将进行垃圾收集。对象
有资格进行垃圾收集。不是引用。因此,如果对象的所有引用
都已终止,则可以说该对象有资格进行垃圾收集。
.对象
符合垃圾收集的条件。不是引用。因此,如果对象的所有引用
都已终止,则可以说该对象符合垃圾收集的条件。
.我通过将WeakReference设置为接口实现解决了所有问题。我通过将WeakReference设置为接口实现解决了所有问题。它是一个引用,与引用对象无关。它是一个引用,它与引用对象无关,最好说“如果对它的所有引用都不存在”。对对象的引用不能变为null;包含对对象的引用的变量可以变为null,但是它不再包含引用,因此引用不会变为null@汤曼德森真言!!编辑。感谢tom的关注。最好说“如果所有对它的引用都不存在”。对对象的引用不能变为null;包含对对象的引用的变量可以变为null,但是它不再包含引用,因此引用不会变为null@汤曼德森真言!!编辑。谢谢汤姆的关心。