谈一谈mmkv的使用

引言

最近微信开源了 mmkv,之前曾经深为 android 跨进程数据共享和通信所困惑,用 contextprovider 里面 sharedpreference,也曾经考虑过用文件读写来实现,可是 Java 端对文件读写跨进程操作实在是没有很大可操作余地,ndk写的话又太耗时而且无法保障测试性能等等问题。现在开源的 mmkv 正好弥补来这一块空缺,而且结果微信检验,在性能和安全方面感觉还是比较靠谱的。

详解

跨进程数据共享主要有以下问题:

  1. 多进程数据如何保持数据一致性即写更新,读的都是最新的
  2. 如何保证稳定性和高效性,降低性能消耗

mmkv 最初的设计并不是为了考虑多进程情况。主要是提高了 key-value 存储的性能。

  1. 使用 protobuf 二进制来存储数据。作为高效数据压缩编码方式,无疑提高了写入和读取性能
  2. 增量更新。通过将修改数据写在后面,等待内存满了之后触发重整进行整理。提高了修改操作的性能,不需要再去查询旧数据进行修改。当然在不断触发内存重整的情况下会大大损耗性能(回到),但一般情况下这明显是低概率事件.且存储限制会指数增长。
  3. mmap 文件映射内存,省去一次拷贝的时机。

而之后考虑 android 多进程的情况,针对多进程需要考虑情况:

  1. 指示器。拿文件前面几个字节作为当前写的位置。多进程模式下,每个进程读写时候都要检查一下当前和内存是否一致。不一致则需要读取新写的。
  2. 锁。使用了文件读写锁,在外部做了封装,可以更好支持。
  3. 增加了 Ashmem 的支持。

使用

  1. 使用简单,最好直接使用 static 的依赖,因为普通的依赖会添加 libc++_shared.so ,会导致包比 static 大2倍以上
implementation 'com.tencent:mmkv-static:1.0.19'
  1. 性能测试,多进程和单进程性能相差很小。1000 次写稳定在几十毫秒,在新机器上会达到20、30毫秒内。1000 次读能稳定在10毫秒左右。偶尔可能会有波动。总体看性能比读写 file 高10倍以上,比 sharedference 写高百倍(因为 sharedference 就算使用 apply,在最后未完成也要补回来),读因为 sharedference 是内存操作所以相差不大。
  2. 因为 mmkv 在 native 层做了较多缓存,所以在使用是可以不需要考虑创建性能单例等等问题

注意事项

  • 使用 file 没有特别注意的地方,但是要注意自己不要每次都添加很大的数据,很频繁触发内存重整,效率会很低。
  • 使用 Ashmem 的话,有很多注意地方。可以的话能不用就不用,使用 file + 逻辑来代替
  • 内部实现实际使用了 MMKVContentProvider 来传递文件描述符
  • 在 X86 某些机型上很容易 anr
  • 如果 MMKVContentProvider 所在进程挂了重新启动,会导致 ashmem 生成新的,和其它还存在进程不一致。
  • 因为 mmkv 无法保障原子性操作。类似乐观锁的需要自己实现
  • mmkv 采用 mmap,实际上 binder 内部实现也是使用 mmap。所以不需要过多担心内部稳定性

最后

如果你看到了这里,觉得文章写得不错就给个赞呗!欢迎大家评论讨论!如果你觉得那里值得改进的,请给我留言。一定会认真查询,修正不足,定期免费分享技术干货。喜欢的小伙伴可以关注一下哦。谢谢!

  • 7
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值