MMKV的简单实用一
MMKV 是基于 mmap 内存映射的移动端通用 key-value 组件,底层序列化/反序列化使用 protobuf 实现,性能高,稳定性强。从 2015 年中至今在微信上使用,其性能和稳定性经过了时间的验证。近期也已移植到 Android / macOS / Windows 平台,一并开源。
MMKV官方链接
MMKV 源起
在微信客户端的日常运营中,时不时就会爆发特殊文字引起系统的 crash,参考文章,文章里面设计的技术方案是在关键代码前后进行计数器的加减,通过检查计数器的异常,来发现引起闪退的异常文字。在会话列表、会话界面等有大量 cell 的地方,希望新加的计时器不会影响滑动性能;另外这些计数器还要永久存储下来——因为闪退随时可能发生。这就需要一个性能非常高的通用 key-value 存储组件,我们考察了 SharedPreferences、NSUserDefaults、SQLite 等常见组件,发现都没能满足如此苛刻的性能要求。考虑到这个防 crash 方案最主要的诉求还是实时写入,而 mmap 内存映射文件刚好满足这种需求,我们尝试通过它来实现一套 key-value 组件
MMKV 原理
- 内存准备
通过 mmap 内存映射文件,提供一段可供随时写入的内存块,App 只管往里面写数据,由操作系统负责将内存回写到文件,不必担心 crash 导致数据丢失。 - 数据组织
数据序列化方面我们选用 protobuf 协议,pb 在性能和空间占用上都有不错的表现。 - 写入优化
考虑到主要使用场景是频繁地进行写入更新,我们需要有增量更新的能力。我们考虑将增量 kv 对象序列化后,append 到内存末尾。 - 空间增长
使用 append 实现增量更新带来了一个新的问题,就是不断 append 的话,文件大小会增长得不可控。我们需要在性能和空间上做个折中。
优点
多进程访问
通过与 Android 开发同学的沟通,了解到系统自带的 SharedPreferences 对多进程的支持不好。现有基于 ContentProvider 封装的实现,虽然多进程是支持了,但是性能低下,经常导致 ANR。考虑到 mmap 共享内存本质上的多进程共享的,我们在这个基础上,深入挖掘了 Android 系统的能力,提供了可能是业界最高效的多进程数据共享组件。具体实现原理我们中秋节后分享,心急的同学可以前往 GitHub 查看源码和 wiki 文档。匿名内存
在多进程共享的基础上,考虑到某些敏感数据(例如密码)需要进程间共享,但是不方便落地存储到文件上,直接用 mmap 不合适。我们了解到 Android 系统提供了 Ashmem 匿名共享内存的能力,发现它在进程退出后就会消失,不会落地到文件上,非常适合这个场景。我们很愉快地提供了 Ashmem MMKV 的功能。数据加密
不像 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的简单实用一相关推荐
- 一个简单实用的,基于EF的三层架构
到底什么样的框架才是好框架呢?或许不同人有不同的看法.我个人觉一个好的框架,最重要的要是简单实用,能快速适开发,可维护性高(不会出现复制黏贴的代码),并能快速响应各种业务场景的变化的框架,同时性能不会 ...
- html 可调节进度条控件,jQuery简单实用的轻量级进度条插件
jQMeter是一款简单实用的轻量级进度条jQuery插件,它可以显示为水平或垂直进度条,进度条加载时带有动画特效,你只需要简单的传入一些参数到jQMeter对象的构造函数中就可以完成你想要的进度条效 ...
- 分享几个用 Python 给图片添加水印的方法,简单实用
作者 |俊欣 来源 |关于数据分析与可视化 今天来分享几种可以给图片添加水印的方法,都是十分的简单实用,大家在看了之后也可以私底下去自己试试,有些方法需要的代码量就比较少,有些方法需要的代码量就稍微多 ...
- matlab简单程序实例_visual basic VB.NET实例系列教程第一节(简单实用抽奖程序)...
近期疫情原因,工作比较不忙,所以打算出一套零基础,VB.NET实例系列入门教程,实用又好玩,带大家进入VB的编程世界里,希望这套图文教程能帮到有需要的人! 第一节(简单实用抽奖程序) 内容准备:编译环 ...
- 用aspnetpager实现datalist分页(绝对的简单实用)
微软的Datalist在做电子相册时候必不可少,但是不支持分页功能,都出到2008了还是没有分页功能,幸好网上有个专业的分页空间aspnetpager,帮我们解决了大问题,说实在话的,网上关于data ...
- 这两天老是有兄弟问到Vue的登陆和注册,登陆成功留在首页,没有登录回到登录页面,现在我用最简单实用的方法实现(两分钟技就看懂)...
其实登录注册,并且登录一次保持登录的状态,是每个项目都需要实现的功能. 网上也有很多的方法,不过,不是通俗易懂,在这里说一下我自己的方法,非常简单实用 核心就是用localStorage存.取数据,这 ...
- sql 拼接int类型的字段_一套简单实用的SQL脚本(下篇)
点击上方SQL数据库开发,关注获取SQL视频教程 SQL专栏 SQL数据库基础知识汇总 SQL数据库高级知识汇总 之前已经分享了一部分内容<一套简单实用的SQL脚本(上篇)>接上一章我们继 ...
- python读取excel表格-python读写Excel表格的实例代码(简单实用)
安装两个库:pip install xlrd.pip install xlwt 1.python读excel--xlrd 2.python写excel--xlwt 1.读excel数据,包括日期等数据 ...
- 『中级篇』k8s的NodePort类型Service以及Label的简单实用(68)
原创文章,欢迎转载.转载请注明:转载自IT人故事会,谢谢! 原文链接地址:『中级篇』k8s的NodePort类型Service以及Label的简单实用(68) 上次主要说了service的一种类型,c ...
最新文章
- python反射实例化_Python类反射机制使用实例解析
- linux c 编译警告 warning: this decimal constant is unsigned only in ISO C90
- Spring4 MVC + REST + List + Bootstrap 简单示例
- shell中的>/dev/null 2>1(转载)
- php如何进行错误处理,php如何自定义错误处理
- leetcode151. 翻转字符串里的单词
- {WP7/WP8·获取屏幕大小}
- PHP和Java的主要区别有哪些呢?
- DirectX SDK 安装时出现错误 [Error Code:S1023] 的解决方案
- matlab拟合函数求系数,matlab 求拟合函数的系数
- 找特征点的算法 SIFT和SURF算法
- FastReport报表控件使用技巧总结
- Linux回到桌面快捷键
- 【个人亲历】上海市人才引进落户最详细的流程记录说明
- 图像卡通化生成(Image Cartoonization):最新最全19篇汇总
- 4k纸是几厘米乘几厘米_4k纸多大,纸张的大小规格
- 怎么把安卓手机便签小工具添加到手机桌面显示呢?
- redis源码注释二:简单字符串sds.c sds.h
- 2021-04-10 仿牛客网第六章
- 【Ware】免费的格式转换软件推荐
热门文章
- rand和srand的用法(转载)
- OCR识别系列之一-----文档字符识别
- linux 怎么改系统字体,linux系统终端修改字体的方法
- 黑马程序员java学习打卡----程序流程控制
- 5-2 学习打卡(11.7)
- Global Illumination_Spherical Harmonic Lighting(球谐光照)
- python简单代码运用到桌面壁纸_五行Python代码自动换你的电脑桌面壁纸(内附源码和exe)...
- Git冲突:Your local changes would be overwritten by merge. Commit, stash or revert them to proceed.
- 线路编码(NRZ,NRZI,8B/10B,Manchester等)
- 【IP协议(一)】——IP数据报格式及其含义,IP数据报的切分