这个Kotlin-Singleton实现,将成为垃圾回收的挽歌吗



我有一个像singleton一样的类(实例没有得到保护,无法再次创建(:

class FooInteractorFactory(private val someEvent: SomeEvent) {
companion object {
lateinit var fooFactory: FooInteractorFactory
fun initialize(someEvent: SomeEvent) {
fooFactory = FooInteractorFactory(someEvent)
}
}
fun createSomeObject(): SomeObject {
return SomeObject(someEvent)
}
}

这个"singleton"正在这个类中初始化:

class FooImpl : SomeEvent {
init {
FooInteractorFactory.initialize(this)
}
...
}

并且FooImpl在活动中的生命周期函数onCreate()内被实例化:

class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val foompl = FooImpl()
}
...
}

我的问题是FooInteractorFactorySomeEventSomeObject,其中一些会泄漏或不符合垃圾收集条件?

正如文件所说,

当且仅当垃圾收集器可以回收类或接口的定义类加载器时,才可以卸载该类或接口。

这将是合格的,但是,我不确定。我只是添加到应用程序LeakCanary,但是,Leak从未发生过。

我想根据你们每个人的经历来确定。

编辑

这就是FooInteractorFactory在反编译的java代码中的样子:

public final class FooInteractorFactory {
private final SomeEvent someEvent;
@NotNull
public static FooInteractorFactory fooFactory;
@NotNull
public final FooInteractorFactory createSomeObject() {
return new SomeObject(this.someEvent);
}
public FooInteractorFactory(@NotNull SomeEvent someEvent) {
this.someEvent = someEvent;
}

public static final class Companion {
@NotNull
public final FooInteractorFactory getFooFactory() {
return FooInteractorFactory.access$getFooFactory$cp();
}
public final void setFooFactory(@NotNull FooInteractorFactory var1) {
FooInteractorFactory.fooFactory = var1;
}
public final void initialize(@NotNull SomeEvent someEvent) {
((FooInteractorFactory.Companion)this).setFooFactory(new FooInteractorFactory(someEvent));
}
}
}

FooInteractorFactory是同一类的静态引用。

AFAIK LeakCanary只检测泄漏的活动,因此它并不是为检测所有内存泄漏而设计的(最后,现在应该如何检测哪个实例应该被垃圾收集,哪个不应该?(。

此外,您作为引用附加的内容是关于Class<?>的,而不是关于实例的。我的意思是,它说明了整个Class定义,这些定义存储在永久生成或元空间中(取决于Java版本(。

关于你的问题:垃圾收集器通常以下一种方式工作——它从名为GC根的引用开始,然后通过这些根的引用遍历所有对象,将它们标记为"活动",并从所有未标记为活动的对象中回收内存(我的意思是,这些对象通过GC根不可用(。被称为GC根的参考文献有:

  1. 局部变量
  2. static变量
  3. 活动Threads
  4. JNI参考

我怀疑您提到的任何Class对象是否会从JVM中卸载,以防您没有定义自己的ClassLoader或打乱它们的生命周期。谈实例:

我有一个像singleton一样的类(实例没有被保护以再次创建(

如果comanion的对象fooFactory引用了对象A,然后用对象B重新分配,那么如果A没有被任何其他GC根引用或通过GC根可用的中间引用引用引用,那么在几个GC循环中,此内容将被垃圾收集。

所有其他实例也是如此。

最新更新