跳到主要内容

MMKV

问题

MMKV 的原理是什么?为什么比 SharedPreferences 快?

答案

核心原理

MMKV(Memory-Mapped Key-Value)是腾讯开源的高性能键值存储,核心优势来自两个技术:

MMKV vs SharedPreferences

特性SharedPreferencesMMKV
文件格式XML 文本Protobuf 二进制
写入方式全量序列化写入增量追加
IO 模型read/write 系统调用mmap 内存映射
跨进程
写入性能快 100 倍+

基本使用

// 初始化(Application.onCreate)
MMKV.initialize(this)

// 获取实例
val kv = MMKV.defaultMMKV()

// 读写操作
kv.encode("username", "John")
kv.encode("login_count", 42)
kv.encode("is_vip", true)

val name = kv.decodeString("username", "")
val count = kv.decodeInt("login_count", 0)
val vip = kv.decodeBool("is_vip", false)

跨进程使用

// 多进程模式
val kv = MMKV.mmkvWithID("shared_data", MMKV.MULTI_PROCESS_MODE)

// 进程 A 写入
kv.encode("token", "abc123")

// 进程 B 直接读取(通过 mmap 共享内存空间)
val token = kv.decodeString("token", "")

从 SP 迁移

val oldSp = getSharedPreferences("old_prefs", MODE_PRIVATE)
val kv = MMKV.defaultMMKV()
kv.importFromSharedPreferences(oldSp)
oldSp.edit().clear().apply() // 清除旧数据
选择建议
  • 官方项目 / 简单配置 → DataStore(Google 官方推荐,Jetpack 生态)
  • 高频读写 / 跨进程 / 性能敏感 → MMKV(性能最优)
  • 遗留项目 → 优先迁移到 MMKV(API 兼容 SP,迁移成本低)

常见面试问题

Q1: mmap 为什么比传统文件 IO 快?

答案

传统 IO:App → 系统调用 → 内核缓冲区 → 磁盘,每次 read/write 都需要用户态和内核态切换。

mmap:将文件直接映射到进程的虚拟内存空间,App 操作内存即操作文件,不需要系统调用开销。操作系统通过页面缓存管理脏页回写,崩溃时也能保证数据不丢失(内核负责回写)。

Q2: MMKV 的增量追加如何避免文件无限增长?

答案

MMKV 写入时追加到文件末尾(同一个 key 写多次会有多条记录)。当文件中无效数据达到一定比例时,触发文件重整:遍历所有 key-value,只保留每个 key 的最新值,重新写入。这比 SP 的每次全量写入仍然高效得多。

相关链接