提问人:rowjammer 提问时间:9/21/2023 最后编辑:rowjammer 更新时间:10/26/2023 访问量:65
在 iOS 上使用 MongoDB Realms 时出现 KMM 内存泄漏(RAM + 磁盘)问题
KMM Memory Leak (RAM + Disk) issue when using MongoDB Realms on iOS
问:
我过去一直在使用 Java Realm 开发 Android 应用程序,最近我将其迁移到 Kotlin Multiplatform,以使其与 iOS 兼容。经过测试,似乎通过在 iOS 环境中运行它,我的内存因泄漏而饱和,这影响了 RAM 和磁盘(它会在几周的测试中完全填满,全部为 64Gb)。因此,我制作了一个非常简单的降级版本,展示了它到底失败了什么。简而言之,通过调用 realm.open 和 realm.close 方法,我泄漏了内存(根据 Xcode 上的内存图,realm_scheduler 实例,但任何与领域相关的内容似乎都会在其中创建过多的实例)。
简而言之,我要在 iOS 上运行的 Swift 代码只执行这个,它会创建一个计时器,每 .1 秒从 RealmLeaker 的实例调用 leak():
var leaker = RealmLeaker()
// Code skipped here for readability
NavigationView {
Text("A")
}
.onAppear() {
var timer1 = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { timerI in
// Leaking
leaker.leak()
}
}
在 KMM 方面,这里是 RealmLeaker 类:
class RealmLeaker {
fun leak() {
val config = RealmConfiguration.Builder(setOf(TestClass::class))
.build()
// This should simply open, then close the realm. Note that if you comment everything below this, there is no leak.
val realm: Realm = Realm.open(config)
realm.close()
}
}
为了获得更多上下文,这是我在 Kotlin 端使用的“TestClass”:
// This class isn't really useful. Only there to showcase the leak, its properties are outside the scope of the problem.
class TestClass : RealmObject{
@PrimaryKey
var _id : String = "0"
var value : Boolean = false
var key : String = "test"
}
从逻辑上讲,这段代码应该只是打开和关闭 Realm,不会丢失内存,但它会填满我的 RAM 和磁盘内存。
下面是一个重现错误的存储库: GitHub - ALXgba/realmKMMIssue:在 iOS 环境中运行时,在 KMM 项目中使用 Kotlin API 时发生内存泄漏。 1
我确实在 MongoDB Realms GitHub 页面上打开了一个问题,但由于他们还没有回答,我希望我错过的内容可能是基本的,并且我可能会在我的代码中修复它,因为我希望快速规避这个问题。这是问题页面: https://github.com/realm/realm-kotlin/issues/1501
虽然使用 Xcode 调试图时问题似乎并不那么可怕,但如前所述,它没有清楚地表明应用程序在磁盘上的大小也在无限增长。这意味着如果用户想要频繁使用这个应用程序,他们需要定期卸载并重新安装它,并在此过程中擦除 Realm。此外,使用的 RAM 似乎以很小的速度增长,但我在我的实际应用程序(不是测试应用程序)中观察到它的增长速度足够快,以至于在一个小时左右后崩溃,因为整个 RAM 被堵塞了。
答:
对于任何尝试此问题的人:
Realms 存在一个内部问题,简而言之,它涉及 iOS 等价于 GC 的循环依赖关系。该问题已通过以下拉取请求关闭: https://github.com/realm/realm-kotlin/pull/1530 它尚未在实际版本中推送,但使用与其当前分支链接的 1.11.2-SNAPSHOT 可以解决问题。(https://github.com/realm/realm-kotlin/tree/releases;有关详细信息,请参阅 README.md 中的“使用快照”。
评论