MMKV 基于 mmap 的高性能通用 key-value 组件

2024-02-17 17:08

本文主要是介绍MMKV 基于 mmap 的高性能通用 key-value 组件,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

学前介绍

MMKV 是基于 mmap 内存映射的 key-value 组件,底层序列化/反序列化使用 protobuf 实现,性能高,稳定性强。从 2015 年中至今,在 iOS 微信上使用已有近 3 年,其性能和稳定性经过了时间的验证。

官方MMKV地址


为什么要替代SharedPreferences?

  • 1,数据加密。

在 Android 环境里,数据加密是非常必须的,SP实际上是把键值对放到本地文件中进行
存储。如果要保证数据安全需要自己加密,MMKV 使用了 AES CFB-128 算法来加密/解密。

  • 2,多进程共享。

系统自带的 SharedPreferences 对多进程的支持不好。现有基于 ContentProvider 封装的实现,虽然多进程是支持了,但是性能低下,经常导致 ANR。考虑到 mmap 共享内存本质上是多进程共享的,MMKV 在这个基础上,深入挖掘了 Android 系统的能力,提供了可能是业界最高效的多进
程数据共享组件。

  • 3,匿名内存。

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

  • 4,效率更高。

MMKV 使用protobuf进行序列化和反序列化,比起SP的xml存放方式,更加高效。可以看看下面的博文。
源码解析SharedPreferences你不知道的缺点

  • 5,支持从 SP迁移,

如果你之前项目里面都是使用SP,现在想改为使用MMKV,只需几行代码即可将之前的SP实现迁移到MMKV。

学习内容:

MMKV是基于mmap来实现的,所以mmap是关键。
为了讲清mmap的原理我们首先需要了解一点基础知识。

  • 物理内存
    真实的硬件设备(内存条)。容量较小。
  • 虚拟内存
    利用磁盘空间虚拟出的一块逻辑内存,用作虚拟内存的磁盘空间被称为交换空间。为了满足物理内存的不足而提出的策略)
int a = 10;
int *p = &a;

大家看上面的代码,是不是特别简单,但我问个问题,这行代码在运行的时候p指向的是物理内存还是虚拟内存。答案是 虚拟内存
接下来就要解释为什么?这就要涉及到MMU
MMU中文名是内存管理单元,有时称作分页内存管理单元,主要用来管理虚拟存储器、物理存储器的控制线路,同时也负责虚拟地址映射为物理地址,以及提供硬件机制的内存访问授权、多任务多进程操作系统。
在这里插入图片描述
linux使用MMU的机器都采用分页机制。虚拟地址空间以为单位进行划分,而相应的物理地址空间也被划分,其使用的单位称为页帧,页帧和页必须保持相同,因为内存与外部存储器之间的传输是以页为单位进行传输的。​虚拟内存的哪个页面映射到物理内存的哪个页帧是通过页表(Page Table)来描述的页表保存在物理内存中。
这里还要讲一下交换区的概念:
实际上就是一块磁盘空间(硬盘空间)。虚拟内存与物理内存映射的时候,是将虚拟内存的代码放到交换区中,以后在CPU想要执行相关的指令或者数据时,如果内存中没有,先去交换区将需要的指令与数据映射到物理内存,然后CPU再执行,而一个进程中不可能全部的代码会同时运行,所以在同一时间,每次只有进程的少部分代码会在物理内存中运行 ,大部分代码依然位于磁盘中(存储器硬盘)。

交换区里面存放的是大部分的可执行代码与数据。而物理内存中,执行的是少部分的可执行代码与数据,其它未执行的大部分代码都在磁盘/硬盘中。

那么此时就需要从交换区获取程序的代码,将它拿到物理内存执行。那么一次拿多少代码过来呢?这是一个问题!

为了CPU的高效执行以及方便的内存管理,每次需要拿一个页的代码。这个页,指的是一段连续的存储空间(常见的是4Kb),也叫作块。

这里我们稍微扩充一下:Intent 是可以传递值的,那这个传值的大小是多大呢?

1M-8k = 2k 这里为什么要减2k 是因为 这里面存放了一些附加信息比如信息头。

终于前期的铺垫终于讲完了,但你肯定疑惑的摸不着头脑,这跟我要学的mmap又什么瓜系呢?

其实mmap就是一种内存映射文件的方法,即将一个文件或者其它对象映射到进程的地址空间,实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系。
Linux的内存分用户空间跟内核空间,同时页表有也分两类,用户空间页表跟内核空间页表,每个进程有一个用户空间页表,但是系统只有一个内核空间页表。
而Binder mmap的关键是:更新用户空间对应的页表的同时也同步映射内核页表,让两个页表都指向同一块地址,这样一来,数据只需要从A进程的用户空间,直接拷贝到B所对应的内核空间,而B所对应的内核空间在B进程的用户空间也有相应的映射,这样就无需从内核拷贝到用户空间了。

  • copy_from_user() //将数据从用户空间拷贝到内核空间
  • copy_to_user() //将数据从内核空间拷贝到用户空间
    mmap大致流程如下图:
    在这里插入图片描述

学习产出:

DEMO

这篇关于MMKV 基于 mmap 的高性能通用 key-value 组件的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/718448

相关文章

Spring组件实例化扩展点之InstantiationAwareBeanPostProcessor使用场景解析

《Spring组件实例化扩展点之InstantiationAwareBeanPostProcessor使用场景解析》InstantiationAwareBeanPostProcessor是Spring... 目录一、什么是InstantiationAwareBeanPostProcessor?二、核心方法解

C++ RabbitMq消息队列组件详解

《C++RabbitMq消息队列组件详解》:本文主要介绍C++RabbitMq消息队列组件的相关知识,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1. RabbitMq介绍2. 安装RabbitMQ3. 安装 RabbitMQ 的 C++客户端库4. A

解读@ConfigurationProperties和@value的区别

《解读@ConfigurationProperties和@value的区别》:本文主要介绍@ConfigurationProperties和@value的区别及说明,具有很好的参考价值,希望对大家... 目录1. 功能对比2. 使用场景对比@ConfigurationProperties@Value3. 核

Nginx使用Keepalived部署web集群(高可用高性能负载均衡)实战案例

《Nginx使用Keepalived部署web集群(高可用高性能负载均衡)实战案例》本文介绍Nginx+Keepalived实现Web集群高可用负载均衡的部署与测试,涵盖架构设计、环境配置、健康检查、... 目录前言一、架构设计二、环境准备三、案例部署配置 前端 Keepalived配置 前端 Nginx

SQL 外键Foreign Key全解析

《SQL外键ForeignKey全解析》外键是数据库表中的一列(或一组列),用于​​建立两个表之间的关联关系​​,外键的值必须匹配另一个表的主键(PrimaryKey)或唯一约束(UniqueCo... 目录1. 什么是外键?​​ ​​​​2. 外键的语法​​​​3. 外键的约束行为​​​​4. 多列外键​

PyQt6中QMainWindow组件的使用详解

《PyQt6中QMainWindow组件的使用详解》QMainWindow是PyQt6中用于构建桌面应用程序的基础组件,本文主要介绍了PyQt6中QMainWindow组件的使用,具有一定的参考价值,... 目录1. QMainWindow 组php件概述2. 使用 QMainWindow3. QMainW

C#实现高性能Excel百万数据导出优化实战指南

《C#实现高性能Excel百万数据导出优化实战指南》在日常工作中,Excel数据导出是一个常见的需求,然而,当数据量较大时,性能和内存问题往往会成为限制导出效率的瓶颈,下面我们看看C#如何结合EPPl... 目录一、技术方案核心对比二、各方案选型建议三、性能对比数据四、核心代码实现1. MiniExcel

浅谈Redis Key 命名规范文档

《浅谈RedisKey命名规范文档》本文介绍了Redis键名命名规范,包括命名格式、具体规范、数据类型扩展命名、时间敏感型键名、规范总结以及实际应用示例,感兴趣的可以了解一下... 目录1. 命名格式格式模板:示例:2. 具体规范2.1 小写命名2.2 使用冒号分隔层级2.3 标识符命名3. 数据类型扩展命

Redis 热 key 和大 key 问题小结

《Redis热key和大key问题小结》:本文主要介绍Redis热key和大key问题小结,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录一、什么是 Redis 热 key?热 key(Hot Key)定义: 热 key 常见表现:热 key 的风险:二、

redis过期key的删除策略介绍

《redis过期key的删除策略介绍》:本文主要介绍redis过期key的删除策略,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录第一种策略:被动删除第二种策略:定期删除第三种策略:强制删除关于big key的清理UNLINK命令FLUSHALL/FLUSHDB命