-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
design_eng
By using mmap
to memory-map a file, MMKV provides a memory block that can be written to at any time. The application writes data directly into this memory block, while the operating system handles writing the data back to the file. This ensures data integrity even if the app crashes.
For data serialization, we chose the Protocol Buffers (protobuf) protocol, which offers excellent performance and space efficiency. Since MMKV is a general-purpose key-value (KV) component, keys are restricted to strings, while values can be of various types (int, bool, double, etc.). To generalize value handling, we serialize values into a unified memory buffer using protobuf, then serialize the entire KV object into memory.
message KV {
string key = 1;
bytes value = 2;
}
Example usage:
- (BOOL)setInt32:(int32_t)value forKey:(NSString *)key {
NSData *data = PBEncode(value);
return [self setData:data forKey:key];
}
- (BOOL)setData:(NSData *)data forKey:(NSString *)key {
KV kv = { key, data };
NSData *buf = PBEncode(kv);
return [self write:buf];
}
Standard protobuf does not support incremental updates, requiring full writes for every modification. To address frequent write-update scenarios, MMKV implements incremental updates: new KV objects are serialized and appended directly to the end of the memory block. This means multiple versions of the same key may exist, with the latest value always at the end. During initialization, MMKV scans all entries and retains only the last occurrence of each key, ensuring data validity.
The append-only approach introduces uncontrolled file growth (e.g., repeated updates to a single key could bloat the file to hundreds of MB or even GB, despite needing only ~1 KB). To balance performance and space, MMKV:
- Allocates space in memory page size units.
- Operates in append mode until space is exhausted.
- Triggers file defragmentation (deduplication) when appending reaches the end.
- If space remains insufficient after deduplication, doubles the file size until adequate.
Pseudocode:
- (BOOL)append:(NSData *)data {
if (space >= data.length) {
append(fd, data);
} else {
NSData *newData = deduplicate(allKV);
if (total_space >= newData.length) {
write(fd, newData);
} else {
while (total_space < newData.length) {
total_space *= 2;
}
ftruncate(fd, total_space);
write(fd, newData);
}
}
}
To guard against file system or OS instability, MMKV adds CRC checksum validation to detect corrupted data. In production environments (e.g., iOS WeChat), we observed approximately 700,000 daily instances of data validation failures.
After porting MMKV to Android, many users requested multi-process support—a feature not originally considered (as iOS lacks multi-process support). This required comprehensive design and meticulous implementation. For details, see Android Multi-Process Design and Implementation.
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
- In English
- 中文