【问题标题】:Kotlin Singleton leaking memory detected by Leak CanaryLeak Canary 检测到 Kotlin Singleton 泄漏内存
【发布时间】:2019-03-13 05:38:06
【问题描述】:

我正在使用这种模式来创建一个单例来帮助我进行 firebase 操作,但不幸的是,它正在泄漏内存,这是我的代码。

class FirebaseDataSource(private val db: FirebaseFirestore,
                     private val firebaseAuth: FirebaseAuth,
                     private val firebaseFunctions: FirebaseFunctions,
                     private val firebaseStorage: FirebaseStorage,
                     private val firebaseInstanceId: FirebaseInstanceId) {
companion object {

    @Volatile
    private var INSTANCE: FirebaseDataSource? = null


    fun getInstance(db: FirebaseFirestore = FirebaseFirestore.getInstance(),
                    firebaseAuth: FirebaseAuth = FirebaseAuth.getInstance(),
                    firebaseFunctions: FirebaseFunctions = FirebaseFunctions.getInstance(),
                    firebaseStorage: FirebaseStorage = FirebaseStorage.getInstance(),
                    firebaseInstanceId: FirebaseInstanceId = FirebaseInstanceId.getInstance()
    ): FirebaseDataSource =
            INSTANCE ?: synchronized(this) {
                INSTANCE
                        ?: FirebaseDataSource(db, firebaseAuth, firebaseFunctions, firebaseStorage, firebaseInstanceId).also { INSTANCE = it }
            }

    fun clearInstance() {
        INSTANCE = null
    }
}
}

我在我的活动中像这样使用它

private val firebaseDataSource = FirebaseDataSource.getInstance()

可以帮助我解决内存泄漏问题,甚至为我的 FirebaseDataSource 提供更好的设计

【问题讨论】:

  • 你永远不会分配给INSTANCE。您只检查它是否为 != null 因此您创建新实例的垃圾邮件
  • @Abdelrhman 是什么让你相信你正在泄漏内存?
  • 我确实在 .also { INSTANCE = it } 中分配了 INSTANCE
  • arf,好的,这很好隐藏但应该可以正常工作,所以忽略我的评论。但是,您使用的是clearInstance吗?
  • 嗯,至少从那条痕迹来看,似乎不是没有被正确清理,或者是 LeakCanary 的误报。

标签: android memory-leaks kotlin leakcanary


【解决方案1】:

Kotlin 具有顶级、线程安全的单例对象。为什么不尝试这样的事情:

object FirebaseDataSource {
  private val db: FirebaseFirestore = FirebaseFirestore.getInstance()
  private val firebaseAuth: FirebaseAuth = FirebaseAuth.getInstance()
  private val firebaseFunctions: FirebaseFunctions = FirebaseFunctions.getInstance()
  private val firebaseStorage: FirebaseStorage = FirebaseStorage.getInstance()
  private val firebaseInstanceId: FirebaseInstanceId = FirebaseInstanceId.getInstance()

  fun doStuff() {
    db.doStuff()
  }
}

然后使用它

FirebaseDataSource.doStuff()

【讨论】:

  • 是的,如果我不想将参数传递给我的类,那就太好了,但如果我想,我认为我不能使用 Kotlin 对象
猜你喜欢
  • 2020-08-29
  • 1970-01-01
  • 1970-01-01
  • 2023-03-20
  • 1970-01-01
  • 2012-07-16
  • 2012-01-22
  • 2021-09-01
相关资源
最近更新 更多