如何防止依赖注入和垃圾收集的循环引用?

Pup*_*Pup 1 java oop garbage-collection dependency-injection actionscript-3

我想我还在尝试理解依赖注入和DI容器的作用.

如果DI意味着较低级别的组件依赖于较高级别的组件,并且没有循环引用,那么该对象是否会被垃圾收集?当我看到垃圾收集(标记和清除)时,它只保留可以使用从程序根开始的一系列引用来跟踪的对象.

由于我自己难以解释,这里有两个UML图,它们呈现了依赖注入的冲突视图,正如我所看到的:

我对DI的原始解释

DI容器注入具有所需引用的组件,并且它们每个都存储对其下一个最高命令的引用.Main类无法访问它们,因此它们应该被垃圾收集. DI Container不存储对其组件的引用

我重新考虑了DI

DI容器注入具有所需引用的组件,并且还维护对每个组件的引用.它们每个都存储对其下一个最高命令的引用.Main类可以通过DI Container访问其中任何一个,因此它们不应该被垃圾收集. DI Container DOES存储对其组件的引用

Ste*_*n C 5

很难理解你实际要问的是什么:

  • 所有主流Java实现都有垃圾收集器,可以使用循环引用收集垃圾......或者通常称为引用循环.因此,从GC的角度来看,没有特别的理由可以避免DI中的参考循环.

  • 如果对象包含对另一个对象的引用,则只要第一个对象可访问,就不会收集第二个对象.DI创建的对象在这方面与其他对象没有什么不同.

  • 显式声明的依赖关系告诉DI框架某些对象需要在其他对象之前构造和连接.他们没有说明需要连接什么,以及是否存在(Java级别)参考周期.


@ JonnyReeve的回答说:

"从广义上讲,只有零引用仍然存在时,引用(对象)才有资格进行垃圾收集(例如:您无法以编程方式访问它)"

这是误导.显然,包含对自身的引用的对象具有(至少)剩余的一个引用,但如果这是唯一的现有引用,则该对象仍然有资格进行垃圾收集.

实际上,如果无法访问对象,则该对象符合收集条件.对于Java,定义(JLS 12.6.1)如下:

"可到达的对象是任何可以从任何活动线程继续计算中访问的对象."

注意这是措辞的谨慎方式.这意味着一个对象可以被垃圾收集,而局部变量仍然引用它...只要JVM可以告诉将来计算不会访问该对象.