引言
最近微信开源了 mmkv,以前曾经深为 android 跨进程数据共享和通讯所困惑,用 contextprovider 里面 sharedpreference,也曾经考虑过用文件读写来实现,但是 Java 端对文件读写跨进程操做实在是没有很大可操做余地,ndk写的话又太耗时并且没法保障测试性能等等问题。如今开源的 mmkv 正好弥补来这一块空缺,并且结果微信检验,在性能和安全方面感受仍是比较靠谱的。android
详解
跨进程数据共享主要有如下问题:c++
- 多进程数据如何保持数据一致性即写更新,读的都是最新的
- 如何保证稳定性和高效性,下降性能消耗
mmkv 最初的设计并非为了考虑多进程状况。主要是提升了 key-value 存储的性能。缓存
- 使用 protobuf 二进制来存储数据。做为高效数据压缩编码方式,无疑提升了写入和读取性能
- 增量更新。经过将修改数据写在后面,等待内存满了以后触发重整进行整理。提升了修改操做的性能,不须要再去查询旧数据进行修改。固然在不断触发内存重整的状况下会大大损耗性能(回到),但通常状况下这明显是低几率事件.且存储限制会指数增加。
- mmap 文件映射内存,省去一次拷贝的时机。
而以后考虑 android 多进程的状况,针对多进程须要考虑状况:安全
- 指示器。拿文件前面几个字节做为当前写的位置。多进程模式下,每一个进程读写时候都要检查一下当前和内存是否一致。不一致则须要读取新写的。
- 锁。使用了文件读写锁,在外部作了封装,能够更好支持。
- 增长了 Ashmem 的支持。
使用
- 使用简单,最好直接使用 static 的依赖,由于普通的依赖会添加 libc++_shared.so ,会致使包比 static 大2倍以上
implementation 'com.tencent:mmkv-static:1.0.19'
复制代码
- 性能测试,多进程和单进程性能相差很小。1000 次写稳定在几十毫秒,在新机器上会达到20、30毫秒内。1000 次读能稳定在10毫秒左右。偶尔可能会有波动。整体看性能比读写 file 高10倍以上,比 sharedference 写高百倍(由于 sharedference 就算使用 apply,在最后未完成也要补回来),读由于 sharedference 是内存操做因此相差不大。
- 由于 mmkv 在 native 层作了较多缓存,因此在使用是能够不须要考虑建立性能单例等等问题
注意事项
-
使用 file 没有特别注意的地方,可是要注意本身不要每次都添加很大的数据,很频繁触发内存重整,效率会很低。bash
-
使用 Ashmem 的话,有不少注意地方。能够的话能不用就不用,使用 file + 逻辑来代替微信
- 内部实现实际使用了 MMKVContentProvider 来传递文件描述符
- 在 X86 某些机型上很容易 anr
- 若是 MMKVContentProvider 所在进程挂了从新启动,会致使 ashmem 生成新的,和其它还存在进程不一致。
-
由于 mmkv 没法保障原子性操做。相似乐观锁的须要本身实现app
-
mmkv 采用 mmap,实际上 binder 内部实现也是使用 mmap。因此不须要过多担忧内部稳定性ide