我认为我仍在努力理解依赖注入(inject)和 DI 容器的作用。
如果 DI 意味着较低级别的组件依赖于较高级别的组件,并且没有循环引用,那么该对象不会被垃圾收集吗?正如我所看到的垃圾收集(标记和清除),它只保留可以使用从程序根开始的引用链跟踪的对象。
由于我难以解释自己,这里有两个 UML 图,它们呈现了我所看到的依赖注入(inject)的相互矛盾的观点:
我对DI的原创解读
DI 容器注入(inject)组件及其所需的引用,并且每个组件都存储对其下一个最高指挥官的引用。主类无法访问它们,因此应该对它们进行垃圾回收。
我对DI的再思考
DI 容器注入(inject)组件及其所需的引用,并维护对每个组件的引用。他们每个人都存储了对他们下一位最高指挥官的引用。 Main 类可以通过 DI 容器访问它们中的任何一个,因此它们不应该被垃圾收集。
最佳答案
很难理解你实际问的是什么:
所有主流 Java 实现都有垃圾收集器,可以收集带有循环引用的垃圾……或者更普遍地称为引用循环。因此,从 GC 的角度来看,没有特别的理由要避免 DI 中的引用循环。
如果一个对象包含对另一个对象的引用,那么只要第一个对象可到达,就不会收集第二个对象。 DI 创建的对象在这方面与其他对象没有什么不同。
显式声明的依赖项告诉 DI 框架某些对象需要先于其他对象构造和连接。他们没有说什么需要连接到什么,以及是否有(Java 级别)引用循环。
@JonnyReeve 的回答是这样说的:
"broadly speaking, a reference (object) will only be eligible for garbage collection when zero references remain (eg: you are not able to programmatically access it)"
这是误导。显然,包含对自身的引用的对象(至少)还剩下一个引用,但如果这是唯一存在的引用,那么该对象仍然有资格进行垃圾回收。
事实上,如果一个对象不是可达的,它就有资格被收集。对于 Java,定义如下 (JLS 12.6.1):
"A reachable object is any object that can be accessed in any potential continuing computation from any live thread."
请注意措辞谨慎。这意味着一个对象可以被垃圾回收,而局部变量仍然引用它......前提是 JVM 可以告诉 future 没有计算将访问该对象。
关于java - 如何通过依赖注入(inject)和垃圾收集来防止循环引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6132728/