iOS环境下KMM使用MongoDB Realm出现RAM及磁盘内存泄漏问题
KMM iOS端Realm频繁打开关闭引发内存与磁盘泄漏问题修复
问题背景
此前基于Java Realm开发Android应用,迁移至KMM适配iOS平台后,发现iOS端运行时出现严重内存泄漏,RAM与磁盘占用持续增长——测试场景下几周即可占满64GB磁盘,实际应用中RAM增长过快会在1小时左右导致崩溃,磁盘无限膨胀迫使用户频繁重装应用。
通过极简复现场景验证:iOS端Swift定时器每0.1秒调用KMM层RealmLeaker类的leak()方法,该方法每次创建新的RealmConfiguration,打开并关闭Realm实例。Xcode内存图显示realm_scheduler等Realm相关实例大量堆积,是泄漏的直接表现。
复现代码
iOS Swift端代码
var leaker = RealmLeaker() // 省略部分代码 NavigationView { Text("A") } .onAppear() { var timer1 = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { timerI in leaker.leak() } }
KMM Kotlin端代码
class RealmLeaker { fun leak() { val config = RealmConfiguration.Builder(setOf(TestClass::class)) .build() val realm: Realm = Realm.open(config) realm.close() } } class TestClass : RealmObject{ @PrimaryKey var _id : String = "0" var value : Boolean = false var key : String = "test" }
问题根源
- 重复创建RealmConfiguration:每次调用
leak()都新建配置实例,Realm内部会为每个配置维护独立的调度器、缓存等资源,频繁创建会导致这些资源无法被回收,持续堆积引发泄漏。 - Realm实例管理不严谨:虽然手动调用了
realm.close(),但配合重复创建的配置,Realm后台调度器无法正常清理,最终导致内存与磁盘资源占用失控。
代码层面修复方案
1. 全局复用RealmConfiguration
将配置改为单例复用,避免重复创建带来的资源冗余:
class RealmLeaker { // 全局复用同一配置实例 private val config = RealmConfiguration.Builder(setOf(TestClass::class)) .build() fun leak() { val realm: Realm = Realm.open(config) realm.close() } }
2. 使用use函数自动管理Realm实例
借助Kotlin的use函数自动完成资源释放,避免手动关闭可能出现的遗漏,同时简化代码:
class RealmLeaker { private val config = RealmConfiguration.Builder(setOf(TestClass::class)) .build() fun leak() { Realm.open(config).use { realm -> // 此处执行Realm相关操作,无需手动调用close() } } }
3. 调整调用频率(可选)
若业务场景允许,降低leak()方法的调用频率(比如从0.1秒调整为更合理的间隔),减少Realm实例的创建销毁次数,进一步缓解资源压力。
额外说明
已针对该问题向MongoDB Realm提交相关Issue,上述方案为代码层面可快速落地的修复手段,复用配置+自动资源管理可有效解决realm_scheduler堆积及磁盘占用增长的问题。
内容的提问来源于stack exchange,提问作者rowjammer
相关产品推荐
相关产品推荐

