-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
home_cn
MMKV 是基于 mmap 内存映射的 key-value 组件,底层序列化/反序列化使用 protobuf 实现,性能高,稳定性强。从 2015 年中至今在微信上使用,其性能和稳定性经过了时间的验证。近期也已移植到 Android / macOS / Windows / POSIX / HarmonyOS NEXT 平台,一并开源。
在微信客户端的日常运营中,时不时就会爆发特殊文字引起系统的 crash,参考文章,文章里面设计的技术方案是在关键代码前后进行计数器的加减,通过检查计数器的异常,来发现引起闪退的异常文字。在会话列表、会话界面等有大量 cell 的地方,希望新加的计时器不会影响滑动性能;另外这些计数器还要永久存储下来——因为闪退随时可能发生。这就需要一个性能非常高的通用 key-value 存储组件,我们考察了 SharedPreferences、NSUserDefaults、SQLite 等常见组件,发现都没能满足如此苛刻的性能要求。考虑到这个防 crash 方案最主要的诉求还是实时写入,而 mmap 内存映射文件刚好满足这种需求,我们尝试通过它来实现一套 key-value 组件。
-
内存准备
通过 mmap 内存映射文件,提供一段可供随时写入的内存块,App 只管往里面写数据,由操作系统负责将内存回写到文件,不必担心 crash 导致数据丢失。 -
数据组织
数据序列化方面我们选用 protobuf 协议,pb 在性能和空间占用上都有不错的表现。 -
写入优化
考虑到主要使用场景是频繁地进行写入更新,我们需要有增量更新的能力。我们考虑将增量 kv 对象序列化后,append 到内存末尾。 -
空间增长
使用 append 实现增量更新带来了一个新的问题,就是不断 append 的话,文件大小会增长得不可控。我们需要在性能和空间上做个折中。
更详细的设计原理参考 MMKV 原理。
推荐使用 Maven:
dependencies {
implementation 'com.tencent:mmkv:2.0.0'
// replace "2.0.0" with any available version
}
从 v1.2.8 起, MMKV 迁移到 Maven Central。老版本 (<= v1.2.7) 仍然在 JCenter。
更多安装指引参考 Android Setup。
MMKV 的使用非常简单,所有变更立马生效,无需调用 sync
、apply
。
在 App 启动时初始化 MMKV,设定 MMKV 的根目录(files/mmkv/),例如在 Application
里:
public void onCreate() {
super.onCreate();
String rootDir = MMKV.initialize(this);
System.out.println("mmkv root: " + rootDir);
//……
}
MMKV 提供一个全局的实例,可以直接使用:
import com.tencent.mmkv.MMKV;
//……
MMKV kv = MMKV.defaultMMKV();
kv.encode("bool", true);
boolean bValue = kv.decodeBool("bool");
kv.encode("int", Integer.MIN_VALUE);
int iValue = kv.decodeInt("int");
kv.encode("string", "Hello from mmkv");
String str = kv.decodeString("string");
MMKV 支持多进程访问,更详细的用法参考 Android Tutorial。
循环写入随机的int
1k 次,我们有如下性能对比:
更详细的性能对比参考 Android Benchmark。
推荐使用 CocoaPods:
- 安装 CocoaPods;
- 打开命令行,
cd
到你的项目工程目录, 输入pod repo update
让 CocoaPods 感知最新的 MMKV 版本; - 打开 Podfile, 添加
pod 'MMKV'
到你的 app target 里面; - 在命令行输入
pod install
; - 用 Xcode 打开由 CocoaPods 自动生成的
.xcworkspace
文件; - 添加头文件
#import <MMKV/MMKV.h>
,就可以愉快地开始你的 MMKV 之旅了。
更多安装指引参考 iOS/macOS Setup。
MMKV 的使用非常简单,无需任何配置,所有变更立马生效,无需调用 synchronize
。在 App 启动时初始化 MMKV(设定 MMKV 的根目录),例如在-[MyApp application: didFinishLaunchingWithOptions:]
里:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// init MMKV in the main thread
[MMKV initializeMMKV:nil];
//...
return YES;
}
MMKV 提供一个全局的实例,可以直接使用:
MMKV *mmkv = [MMKV defaultMMKV];
[mmkv setBool:YES forKey:@"bool"];
BOOL bValue = [mmkv getBoolForKey:@"bool"];
[mmkv setInt32:-1024 forKey:@"int32"];
int32_t iValue = [mmkv getInt32ForKey:@"int32"];
[mmkv setString:@"hello, mmkv" forKey:@"string"];
NSString *str = [mmkv getStringForKey:@"string"];
MMKV 支持多进程访问,更详细的用法参考 iOS/macOS Tutorial。
循环写入随机的int
1w 次,我们有如下性能对比:
更详细的性能对比参考 iOS Benchmark。
推荐使用子工程:
-
获取 MMKV 源码:
git https://github.com/Tencent/MMKV.git
-
添加工程
Windows/MMKV/MMKV.vcxproj
到你的项目里; -
设置你的主工程依赖于
MMKV
工程; -
添加目录
$(OutDir)include
到你主工程的C/C++
->常规
->附加包含目录
; -
添加目录
$(OutDir)
到你主工程的链接器
->常规
->附加库目录
; -
添加
MMKV.lib
到你主工程的链接器
->输入
->附加依赖项
; -
添加头文件
#include <MMKV/MMKV.h>
,就可以愉快地开始你的 MMKV 之旅了。
注意:
- MMKV 默认使用
MT/MTd
运行时库来编译,如果你发现主工程的配置不一样,请修改 MMKV 的配置再编译; - MMKV 使用 Visual Studio 2022 开发,如果你在使用其他版本的 Visual Studio,请修改 MMKV 的
工具集
与主工程一致,再编译.
更多安装指引参考 Windows Setup。
MMKV 的使用非常简单,所有变更立马生效,无需调用 save
、sync
。
在 App 启动时初始化 MMKV,设定 MMKV 的根目录,例如在 main() 里:
#include <MMKV/MMKV.h>
int main() {
std::wstring rootDir = getYourAppDocumentDir();
MMKV::initializeMMKV(rootDir);
//...
}
MMKV 提供一个全局的实例,可以直接使用:
auto mmkv = MMKV::defaultMMKV();
mmkv->set(true, "bool");
std::cout << "bool = " << mmkv->getBool("bool") << std::endl;
mmkv->set(1024, "int32");
std::cout << "int32 = " << mmkv->getInt32("int32") << std::endl;
mmkv->set("Hello, MMKV for Windows", "string");
std::string result;
mmkv->getString("string", result);
std::cout << "string = " << result << std::endl;
MMKV 支持多进程访问,更详细的用法参考 Windows Tutorial。
推荐使用 CMake:
-
获取 MMKV 源码:
git clone https://github.com/Tencent/MMKV.git
-
打开你项目的
CMakeLists.txt
, 添加这几行:
```cmake
add_subdirectory(mmkv/POSIX/src mmkv)
target_link_libraries(MyApp
mmkv)
```
- 添加头文件
#include "MMKV.h"
,就可以愉快地开始你的 MMKV 之旅了。
更多安装指引参考 POSIX Setup。
MMKV 的使用非常简单,所有变更立马生效,无需调用 save
、sync
。
在 App 启动时初始化 MMKV,设定 MMKV 的根目录,例如在 main() 里:
#include "MMKV.h"
int main() {
std::string rootDir = getYourAppDocumentDir();
MMKV::initializeMMKV(rootDir);
//...
}
MMKV 提供一个全局的实例,可以直接使用:
auto mmkv = MMKV::defaultMMKV();
mmkv->set(true, "bool");
std::cout << "bool = " << mmkv->getBool("bool") << std::endl;
mmkv->set(1024, "int32");
std::cout << "int32 = " << mmkv->getInt32("int32") << std::endl;
mmkv->set("Hello, MMKV for Windows", "string");
std::string result;
mmkv->getString("string", result);
std::cout << "string = " << result << std::endl;
MMKV 支持多进程访问,更详细的用法参考 POSIX Tutorial。
推荐使用 OHPM:
ohpm install @tencent/mmkv
更多安装指引参考 HarmonyOS NEXT Tutorial。
MMKV 的使用非常简单,所有变更立马生效,无需调用 save
、sync
。
在 App 启动时初始化 MMKV,设定 MMKV 的根目录,例如在 EntryAbility.onCreate()
里:
import { MMKV } from '@tencent/mmkv';
export default class EntryAbility extends UIAbility {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
let appCtx = this.context.getApplicationContext();
let mmkvRootDir = MMKV.initialize(appCtx);
console.info('mmkv rootDir: ', mmkvRootDir);
……
}
MMKV 提供一个全局的实例,可以直接使用:
import { MMKV } from '@tencent/mmkv';
let mmkv = MMKV.defaultMMKV();
mmkv.encodeBool('bool', true);
console.info('bool = ', mmkv.decodeBool('bool'));
mmkv.encodeInt32('int32', Math.pow(2, 31) - 1);
console.info('max int32 = ', mmkv.decodeInt32('int32'));
mmkv.encodeInt64('int', BigInt(2**63) - BigInt(1));
console.info('max int64 = ', mmkv.decodeInt64('int'));
let str: string = 'Hello OpenHarmony from MMKV';
mmkv.encodeString('string', str);
console.info('string = ', mmkv.decodeString('string'));
let arrayBuffer: ArrayBuffer = StringToArrayBuffer('Hello OpenHarmony from MMKV with bytes');
mmkv.encodeBytes('bytes', arrayBuffer);
let bytes = mmkv.decodeBytes('bytes');
console.info('bytes = ', ArrayBufferToString(bytes));
MMKV 更详细的用法参考 HarmonyOS NEXT Tutorial。
MMKV 以 BSD 3-Clause 证书开源,详情参见 LICENSE.TXT。
具体版本历史请参看 CHANGELOG.md。
如果你有兴趣参与贡献,可以参考 CONTRIBUTING.md。 腾讯开源激励计划 鼓励开发者的参与和贡献,期待你的加入。
为了明确我们对参与者的期望,MMKV 采用了被广泛使用的、由 Contributor Covenant 所定义的行为准则。我们认为它很好地阐明了我们的价值观。有关更多信息请查看 Code of Conduct。
MMKV 不收集、获取或上传任何个人信息,详情参考《MMKV SDK个人信息保护规则》。
MMKV is published under the BSD 3-Clause license. For details check out the LICENSE.TXT.
Check out the CHANGELOG.md for details of change history.
If you are interested in contributing, check out the CONTRIBUTING.md, also join our Tencent OpenSource Plan.
To give clarity of what is expected of our members, MMKV has adopted the code of conduct defined by the Contributor Covenant, which is widely used. And we think it articulates our values well. For more, check out the Code of Conduct.
Check out the FAQ first. Should there be any questions, don't hesitate to create issues.
User privacy is taken very seriously: MMKV does not obtain, collect or upload any personal information. Please refer to the MMKV SDK Personal Information Protection Rules for details.
- In English
- 中文
- In English
- 中文
- In English
- 中文
-
In English
-
中文
-
Golang