帮助中心 广告联系

灵宝信息网-灵宝天气预报-灵宝教育网-灵宝租房-灵宝新闻网-灵宝生活网

热门关键词:

MMKV浅析

来源:原创/投稿/转载 发布时间:2019-10-06

  MMKV是微信开源的一个基于 mmap 内存映射的 key-value 组件,底层序列化/反序列化使用 protobuf 实现,性能高,稳定性强。微信团队为了发现记录特殊文字引起微信 iOS 系统的 crash,在关键代码前后进行计数器的加减,通过检查计数器的异常,来发现引起闪退的异常文字,但同时因为诸多cell的复杂页面情境下希望新加的计时器不会影响性能,另外这些计数器需要永久存储下来——因为闪退随时可能发生,所以亟需高性能的通用 key-value 存储组件,而微信团队在实时写入和高性能的选择标准下,通过对比NSUserDefaults、SQLite 等常见组件,最终选择了mmap 内存映射文件,并将其封装成为了MMKV组件。下面我们来逐步进行了解

  认真分析mmap:是什么 为什么 怎么用这篇文章讲的炒鸡详细,很佩服作者,本人也不想ctrl+c/v一遍,所以直接附上链接入口,看官可自行查阅。但在此处总结下:mmap实现了一种使用内存映射到磁盘文件的方法,将本该属于磁盘文件的对象映射到了进程******空间中,实现文件磁盘******和进程虚拟******空间中一段虚拟******的一一对映关系。实现这样的映射关系后,进程就可以采用指针的方式读写操作这一段内存,而系统会自动(默认并不实时)回写脏页面到对应的文件磁盘上,即完成了对文件的操作而不必再调用read,write等系统调用函数,对文件直接通过内存映射读取从而跨过了页缓存,减少数据拷贝次数,用内存读写取代I/O读写,提高文件读取效率。另外,内核空间对这段区域的修改也直接反映用户空间,从而可以实现不同进程间的文件共享,从而达到进程间通信和进程间共享的目的。简言之,很强大。

  在数据序列化方面微信团队选用了protobuf协议,出于通用化的考虑将多样化的 value 通过 protobuf 协议序列化成统一的内存块(buffer),然后再进行相应存储。

  protobuf是一种灵活高效的序列化结构机制,就像xml,但是protobuf更轻量、更快并且更简单。一旦你限定了你想要的数据结构,那么你就可以使用特殊的构建代码实现对大量数据结构的读写,并且支持多种语言哦~你甚至可以更新你的数据构建,哪怕新的数据结构与老的完全相反,这丝毫不影响已经部署完成的程序。

  也就是说protobuf帮我们轻松实现了序列化和反序列化,即使变更数据结构,也不会产生太大的影响,这对于数据结构多变的实际业务场景来说简直太有必要了。

  因为标准 protobuf并 不提供增量更新的能力,每次写入都必须全量写入。查看代码我们也能看到最底层调用的方法是使用的append而非直接替换:

  1.在程序启动第一次打开 mmkv 时,不断用后读入的 value 替换之前的值,就可以保证数据是最新有效的。

  2.对于空间增长的问题:以内存 pagesize 为单位申请空间,在空间用尽之前都是 append 模式;当 append 到文件末尾时,进行文件重整、key 排重,尝试序列化保存排重结果;排重后空间还是不够用的话,将文件扩大一倍,直到空间足够。所以在每次append之前都会先调用- (BOOL)ensureMemorySize:(size_t)newSize;方法检查一下是否有足够空间,如果没有则按照每次2倍的大小去扩展空间:

  3.另外针对空间增长,mmkv还提供了- (void)trim;方法来提供了通过手动调用减小多余占用内存的功能,正如每次扩增时按2倍扩增,缩减时也是每次除以2:

  微信团队考虑到文件系统、操作系统都有一定的不稳定性,另外增加了 crc 校验,对无效数据进行甄别,根据微信提供的数据:在 iOS 微信现网环境上,观察到有平均约 70w 日次的数据校验不通过。

  CRC即循环冗余校验码(Cyclic Redundancy Check):是数据通信领域中最常用的一种查错校验码,其特征是信息字段和校验字段的长度可以任意选定。循环冗余检查(CRC)是一种数据传输检错功能,对数据进行多项式计算,并将得到的结果附在帧的后面,接收设备也执行类似的算法,以保证数据传输的正确性和完整性。也就是接受方和发送方约定一个用来计算的二进制数(比如x),在整个传输过程中,这个数始终保持不变。循环冗余校验码(CRC)的基本原理是:在K位信息码后再拼接R位的校验码,整个编码长度为N位,因此,这种编码也叫(N,K)码。那么发送方发送时根据约定的x计算出要补全在K位信息码后的R位校验码,然后发送,接收方接收到数据之后通过约定好的x对收到的数据进行校验,即可查验在数据传输过程中有否出错。

本网转载作品的目的在于传递更多信息,并不代表本网赞同其观点或证实其内容的真实性,不承担此类作品侵权行为的直接责任及连带责任。如涉及作品内容、版权等问题,请联系我们进行修改或删除!

联系我们 -