从SharedPreferences到MMKV:Android本地存储的性能革命
在Android开发中,数据持久化是每个应用都无法绕开的话题。当我们需要存储用户偏好设置、登录状态或应用配置时,SharedPreferences(简称SP)往往是开发者的首选方案。然而,随着应用复杂度的提升和用户对流畅体验要求的提高,SP的性能瓶颈逐渐暴露——UI线程卡顿、数据同步延迟、多进程共享困难等问题频频出现。微信团队开源的MMKV正是为解决这些痛点而生,它通过内存映射和Protobuf序列化等技术,将本地存储性能提升了一个数量级。
1. 为什么需要替代SharedPreferences?
SP作为Android官方提供的轻量级存储方案,其易用性毋庸置疑。但深入分析其实现原理,会发现几个致命缺陷:
-
同步阻塞问题:首次初始化SP实例时,文件读取操作会阻塞调用线程直到完成。如果在主线程执行,将直接导致界面卡顿。即使使用
apply()异步提交,数据最终仍需写入磁盘,无法彻底避免延迟。 -
跨进程不可靠:虽然SP支持
MODE_MULTI_PROCESS标志位,但该模式下的文件锁机制存在严重缺陷。多个进程同时读写时,数据一致性无法保证,官方文档已明确不建议使用。 -
写入效率低下:SP的I/O操作需要两次数据拷贝——先拷贝到内核缓冲区,再由系统写入磁盘。对于频繁更新场景,这种设计带来不必要的性能损耗。
-
全量更新机制:每次修改都会触发整个文件重写,而非增量更新。当数据量较大时,这种"杀鸡用牛刀"的方式显然不够高效。
实际测试表明,在Pixel 2 XL设备上执行1000次写入操作,SP平均耗时约700ms,而MMKV仅需50ms左右,性能差距达14倍。
2. MMKV的核心技术解析
2.1 内存映射(mmap)机制
MMKV的基石是Linux的mmap系统调用,它将文件直接映射到进程的地址空间,实现了几项关键优势:
// mmap基本调用形式
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
- 零拷贝IO:省去了用户空间与内核空间之间的数据拷贝,操作内存即操作文件。
- 崩溃安全:由操作系统负责脏页回写,即使应用崩溃也不会丢失数据。
- 共享内存:多个进程映射同一文件时,内存页面可共享,天然支持跨进程通信。
内存映射的工作流程可分为三个阶段:
- 创建映射:建立文件与虚拟地址的关联
- 内存访问:通过指针直接读写映射区域
- 同步解除:系统自动将修改写回磁盘
2.2 Protobuf序列化方案
相比SP使用的XML格式,MMKV采用Google的Protobuf协议进行序列化,其优势体现在:
| 特性 | Protobuf | XML |
|---|

&spm=1001.2101.3001.5002&articleId=160760894&d=1&t=3&u=eb40c69d6f68480aafcf42109ca7645a)
204

被折叠的 条评论
为什么被折叠?



