MMKV 是基于 mmap 内存映射的移动端通用 key-value 组件,底层序列化/反序列化使用 protobuf 实现,性能高,稳定性强。从 2015 年中至今在微信上使用,其性能和稳定性经过了时间的验证。近期也已移植到 Android / macOS / Windows 平台,一并开源。

MMKV官方链接

MMKV 源起
在微信客户端的日常运营中,时不时就会爆发特殊文字引起系统的 crash,参考文章,文章里面设计的技术方案是在关键代码前后进行计数器的加减,通过检查计数器的异常,来发现引起闪退的异常文字。在会话列表、会话界面等有大量 cell 的地方,希望新加的计时器不会影响滑动性能;另外这些计数器还要永久存储下来——因为闪退随时可能发生。这就需要一个性能非常高的通用 key-value 存储组件,我们考察了 SharedPreferences、NSUserDefaults、SQLite 等常见组件,发现都没能满足如此苛刻的性能要求。考虑到这个防 crash 方案最主要的诉求还是实时写入,而 mmap 内存映射文件刚好满足这种需求,我们尝试通过它来实现一套 key-value 组件

MMKV 原理

  1. 内存准备
    通过 mmap 内存映射文件,提供一段可供随时写入的内存块,App 只管往里面写数据,由操作系统负责将内存回写到文件,不必担心 crash 导致数据丢失。
  2. 数据组织
    数据序列化方面我们选用 protobuf 协议,pb 在性能和空间占用上都有不错的表现。
  3. 写入优化
    考虑到主要使用场景是频繁地进行写入更新,我们需要有增量更新的能力。我们考虑将增量 kv 对象序列化后,append 到内存末尾。
  4. 空间增长
    使用 append 实现增量更新带来了一个新的问题,就是不断 append 的话,文件大小会增长得不可控。我们需要在性能和空间上做个折中。

优点

  1. 多进程访问
    通过与 Android 开发同学的沟通,了解到系统自带的 SharedPreferences 对多进程的支持不好。现有基于 ContentProvider 封装的实现,虽然多进程是支持了,但是性能低下,经常导致 ANR。考虑到 mmap 共享内存本质上的多进程共享的,我们在这个基础上,深入挖掘了 Android 系统的能力,提供了可能是业界最高效的多进程数据共享组件。具体实现原理我们中秋节后分享,心急的同学可以前往 GitHub 查看源码和 wiki 文档。

  2. 匿名内存
    在多进程共享的基础上,考虑到某些敏感数据(例如密码)需要进程间共享,但是不方便落地存储到文件上,直接用 mmap 不合适。我们了解到 Android 系统提供了 Ashmem 匿名共享内存的能力,发现它在进程退出后就会消失,不会落地到文件上,非常适合这个场景。我们很愉快地提供了 Ashmem MMKV 的功能。

  3. 数据加密
    不像 iOS 提供了硬件层级的加密机制,在 Android 环境里,数据加密是非常必须的。MMKV 使用了 AES CFB-128 算法来加密/解密。我们选择 CFB 而不是常见的 CBC 算法,主要是因为 MMKV 使用 append-only 实现插入/更新操作,流式加密算法更加合适。事实上这个功能也回馈到了 iOS 版,所以现在两个系统的 MMKV 都有加密功能。

推荐使用 Maven:

dependencies {implementation 'com.tencent:mmkv:1.0.23'// replace "1.0.23" with any available version
}
   private MMKV kv = null;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main)String rootDir = MMKV.initialize(this);kv = MMKV.defaultMMKV();}
   kv.encode("name","张三");kv.encode("boolean",false);kv.encode("int",132);
   boolean bValue = kv.decodeBool("boolean");Log.e("dobValue", "bValue bValue  Bool  " + bValue);String name = kv.decodeString("name");Log.e("dobValue", "bValue bValue  name " + name);int num = kv.decodeInt("int");Log.e("dobValue", "bValue bValue  num " + num);

参考资料:
MMKV——基于 mmap 的高性能通用 key-value 组件

MMKV的简单实用一相关推荐

  1. 一个简单实用的,基于EF的三层架构

    到底什么样的框架才是好框架呢?或许不同人有不同的看法.我个人觉一个好的框架,最重要的要是简单实用,能快速适开发,可维护性高(不会出现复制黏贴的代码),并能快速响应各种业务场景的变化的框架,同时性能不会 ...

  2. html 可调节进度条控件,jQuery简单实用的轻量级进度条插件

    jQMeter是一款简单实用的轻量级进度条jQuery插件,它可以显示为水平或垂直进度条,进度条加载时带有动画特效,你只需要简单的传入一些参数到jQMeter对象的构造函数中就可以完成你想要的进度条效 ...

  3. 分享几个用 Python 给图片添加水印的方法,简单实用

    作者 |俊欣 来源 |关于数据分析与可视化 今天来分享几种可以给图片添加水印的方法,都是十分的简单实用,大家在看了之后也可以私底下去自己试试,有些方法需要的代码量就比较少,有些方法需要的代码量就稍微多 ...

  4. matlab简单程序实例_visual basic VB.NET实例系列教程第一节(简单实用抽奖程序)...

    近期疫情原因,工作比较不忙,所以打算出一套零基础,VB.NET实例系列入门教程,实用又好玩,带大家进入VB的编程世界里,希望这套图文教程能帮到有需要的人! 第一节(简单实用抽奖程序) 内容准备:编译环 ...

  5. 用aspnetpager实现datalist分页(绝对的简单实用)

    微软的Datalist在做电子相册时候必不可少,但是不支持分页功能,都出到2008了还是没有分页功能,幸好网上有个专业的分页空间aspnetpager,帮我们解决了大问题,说实在话的,网上关于data ...

  6. 这两天老是有兄弟问到Vue的登陆和注册,登陆成功留在首页,没有登录回到登录页面,现在我用最简单实用的方法实现(两分钟技就看懂)...

    其实登录注册,并且登录一次保持登录的状态,是每个项目都需要实现的功能. 网上也有很多的方法,不过,不是通俗易懂,在这里说一下我自己的方法,非常简单实用 核心就是用localStorage存.取数据,这 ...

  7. sql 拼接int类型的字段_一套简单实用的SQL脚本(下篇)

    点击上方SQL数据库开发,关注获取SQL视频教程 SQL专栏 SQL数据库基础知识汇总 SQL数据库高级知识汇总 之前已经分享了一部分内容<一套简单实用的SQL脚本(上篇)>接上一章我们继 ...

  8. python读取excel表格-python读写Excel表格的实例代码(简单实用)

    安装两个库:pip install xlrd.pip install xlwt 1.python读excel--xlrd 2.python写excel--xlwt 1.读excel数据,包括日期等数据 ...

  9. 『中级篇』k8s的NodePort类型Service以及Label的简单实用(68)

    原创文章,欢迎转载.转载请注明:转载自IT人故事会,谢谢! 原文链接地址:『中级篇』k8s的NodePort类型Service以及Label的简单实用(68) 上次主要说了service的一种类型,c ...

最新文章

  1. python反射实例化_Python类反射机制使用实例解析
  2. linux c 编译警告 warning: this decimal constant is unsigned only in ISO C90
  3. Spring4 MVC + REST + List + Bootstrap 简单示例
  4. shell中的>/dev/null 2>1(转载)
  5. php如何进行错误处理,php如何自定义错误处理
  6. leetcode151. 翻转字符串里的单词
  7. {WP7/WP8·获取屏幕大小}
  8. PHP和Java的主要区别有哪些呢?
  9. DirectX SDK 安装时出现错误 [Error Code:S1023] 的解决方案
  10. matlab拟合函数求系数,matlab 求拟合函数的系数
  11. 找特征点的算法 SIFT和SURF算法
  12. FastReport报表控件使用技巧总结
  13. Linux回到桌面快捷键
  14. 【个人亲历】上海市人才引进落户最详细的流程记录说明
  15. 图像卡通化生成(Image Cartoonization):最新最全19篇汇总
  16. 4k纸是几厘米乘几厘米_4k纸多大,纸张的大小规格
  17. 怎么把安卓手机便签小工具添加到手机桌面显示呢?
  18. redis源码注释二:简单字符串sds.c sds.h
  19. 2021-04-10 仿牛客网第六章
  20. 【Ware】免费的格式转换软件推荐

热门文章

  1. rand和srand的用法(转载)
  2. OCR识别系列之一-----文档字符识别
  3. linux 怎么改系统字体,linux系统终端修改字体的方法
  4. 黑马程序员java学习打卡----程序流程控制
  5. 5-2 学习打卡(11.7)
  6. Global Illumination_Spherical Harmonic Lighting(球谐光照)
  7. python简单代码运用到桌面壁纸_五行Python代码自动换你的电脑桌面壁纸(内附源码和exe)...
  8. Git冲突:Your local changes would be overwritten by merge. Commit, stash or revert them to proceed.
  9. 线路编码(NRZ,NRZI,8B/10B,Manchester等)
  10. 【IP协议(一)】——IP数据报格式及其含义,IP数据报的切分