我让此类像单身人士一样工作(实例无法确保再次创建):
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)
}
}
该“单身”正在此类中初始化:
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()
}
...
}
我在这里的问题是FooInteractorFactory
,SomeEvent
或SomeObject
,其中有些会泄漏或不符合垃圾收集的条件?
如文档所述,
仅当垃圾回收器可以回收其定义的类加载器时,才可以卸载类或接口。
这将符合资格,但我不确定。我只是添加了应用程序LeakCanary,但是,泄漏从未发生过。
我想根据你们每个人的经验来确定。
编辑
这是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
是同一类的静态引用。
答案 0 :(得分:0)
AFAIK LeakCanary仅检测到泄漏的活动,因此它并非旨在检测所有内存泄漏(最终,现在应该如何对哪个实例进行垃圾回收,而应该不进行垃圾回收?)。
此外,您作为报价单附加的内容是Class<?>
,而不是实例。我的意思是,它说的是整个Class
定义,这些定义存储在永久代或元空间(取决于Java版本)中。
关于您的问题:垃圾收集器通常以另一种方式工作-它从名为GC根的引用开始,然后通过这些根中的引用遍历所有对象,将它们标记为“有效”,并从所有未标记为活动的对象(我的意思是,无法通过GC根目录获得这些对象)。称为GC根的引用是:
static
变量Thread
s 如果您没有定义自己的Class
或弄乱了它们的生命周期,我怀疑您提到的ClassLoader
个对象是否将从JVM中卸载。
谈论实例:
我让这个类像单身人士一样工作(实例没有被确保可以重新创建)
如果comanion的对象fooFactory
引用了对象A
,然后又重新分配了对象B
,则如果A
没有被其他GC根目录或中间引用引用可以通过GC根目录获得,而不是在几个GC周期中,将立即收集该实例。
所有其他实例也是如此。