MMKV( 一) 了解原理

前言:由于知識(shí)點(diǎn)多稽坤,分了多個(gè)記錄倦沧。

MMKV( 一) 了解原理
MMKV (二)基礎(chǔ)知識(shí)點(diǎn)和實(shí)現(xiàn)流程解析
MMKV (三) POSIX線程和文件鎖

導(dǎo)言:MMKV 可以多進(jìn)程通信,實(shí)際上就是共享文件的方式,是基于 mmap 內(nèi)存映射的 key-value 組件牲尺,底層序列化/反序列化使用 protobuf 實(shí)現(xiàn)乘寒,性能高,穩(wěn)定性強(qiáng)万栅,可以跨進(jìn)程

和SharePreference 對(duì)比

sharepreference獲取.png

SharePreference 源碼實(shí)現(xiàn) SharePreferenceImpl.java 對(duì)xml的讀寫(xiě)


sharepreference讀取.png

不能跨進(jìn)程佑钾,如果非要跨進(jìn)程配合ContentProvider使用。

讀寫(xiě)方式:I/O
數(shù)據(jù)格式:XML
k-v 更新:全量更新,n個(gè)k-v->序列化成xml io->文件

MMKV 對(duì)比

I/O vs mmap
數(shù)據(jù)格式:
1烦粒、總體結(jié)構(gòu)
2休溶、整型編碼
3、計(jì)算長(zhǎng)度
增量與全量寫(xiě)入

mmap 和 mmap的優(yōu)缺點(diǎn)

Linux通過(guò)將一個(gè)虛擬內(nèi)存區(qū)域與一個(gè)磁盤(pán)上的對(duì)象關(guān)聯(lián)起來(lái)扰她,以初始化這個(gè)虛擬內(nèi)存區(qū)域的內(nèi)容兽掰,這個(gè)過(guò)程稱為內(nèi)存映射(memory mapping)。

mmap模型.png

對(duì)文件進(jìn)行mmap徒役,會(huì)在進(jìn)程的虛擬內(nèi)存分配地址空間孽尽,創(chuàng)建映射關(guān)系

實(shí)現(xiàn)這樣的映射關(guān)系后,就可以采用指針的方式讀寫(xiě)操作這一段內(nèi)存忧勿,而系統(tǒng)會(huì)自動(dòng)回寫(xiě)到對(duì)應(yīng)的文件磁盤(pán)上

I/O 在系統(tǒng)的操作流程

虛擬內(nèi)存被操作系統(tǒng)劃分成兩塊:用戶空間和內(nèi)核空間杉女,用戶空間是用戶程序代碼運(yùn)行的地方艇拍,內(nèi)核空間是內(nèi)核代碼運(yùn)行的地方。為了安全宠纯,它們是隔離的卸夕,即使用戶的程序崩潰了,內(nèi)核也不受影響婆瓜。

IO讀寫(xiě)模型.png

寫(xiě)文件流程:

1快集、調(diào)用write,告訴內(nèi)核需要寫(xiě)入數(shù)據(jù)的開(kāi)始地址與長(zhǎng)度
2廉白、內(nèi)核將數(shù)據(jù)拷貝到內(nèi)核緩存
3个初、由操作系統(tǒng)調(diào)用,將數(shù)據(jù)拷貝到磁盤(pán)猴蹂,完成寫(xiě)入

優(yōu)點(diǎn)
  • MMAP對(duì)文件的讀寫(xiě)操作只需要從磁盤(pán)到用戶主存的一次數(shù)據(jù)拷貝過(guò)程院溺,減少了數(shù)據(jù)的拷貝次數(shù),提高了文件讀寫(xiě)效率磅轻。
  • MMAP使用邏輯內(nèi)存對(duì)磁盤(pán)文件進(jìn)行映射珍逸,操作內(nèi)存就相當(dāng)于操作文件,不需要開(kāi)啟線程聋溜,操作MMAP的速度和操作內(nèi)存的速度一樣快谆膳;
  • MMAP提供一段可供隨時(shí)寫(xiě)入的內(nèi)存塊,App 只管往里面寫(xiě)數(shù)據(jù)撮躁,由操作系統(tǒng)如內(nèi)存不足漱病、進(jìn)程退出等時(shí)候負(fù)責(zé)將內(nèi)存回寫(xiě)到文件,不必?fù)?dān)心 crash 導(dǎo)致數(shù)據(jù)丟失把曼。

參考微信和美團(tuán)
微信 Mars : https://mp.weixin.qq.com/s/kDPTt9Rtd-PERXXW-UyUlQ

美團(tuán) Logan : https://tech.meituan.com/2018/02/11/logan.html

防止數(shù)據(jù)丟失并提升了讀寫(xiě)效率杨帽。

寫(xiě)入內(nèi)存 寫(xiě)入mmap 寫(xiě)入文件
OS X 17ms 18ms 2685ms
iOS 55ms 55ms 13116ms
Android 283ms 2488ms 7583ms

三大優(yōu)勢(shì)

mmap防止數(shù)據(jù)丟失,提高讀寫(xiě)效率;

精簡(jiǎn)數(shù)據(jù)嗤军,以最少的數(shù)據(jù)量表示最多的信息注盈,減少數(shù)據(jù)大小;

增量更新,避免每次進(jìn)行相對(duì)增量來(lái)說(shuō)大數(shù)據(jù)量的全量寫(xiě)入

缺點(diǎn)

因?yàn)槲覀兪前凑枕?yè)存儲(chǔ)方式型雳,每頁(yè)4096字節(jié)当凡,我們只有100字節(jié)使用,那么整個(gè)頁(yè)4096字節(jié)映射纠俭,所以造成一定的浪費(fèi)

MMKV 存儲(chǔ)的數(shù)據(jù)結(jié)構(gòu)

mmkv數(shù)據(jù)結(jié)構(gòu).png

對(duì)比xml 結(jié)構(gòu)

xml樣例.png

整型編碼

1個(gè)字節(jié)保存7位數(shù)據(jù)
如果寫(xiě)入的數(shù)據(jù) <= 0x7f 那么使用7位即1個(gè)字節(jié)表示沿量。
如果寫(xiě)入的數(shù)據(jù) > 0x7f 那么先記錄低7位數(shù)據(jù),并將最高位設(shè)為1冤荆,繼續(xù)執(zhí)行判斷

整型編碼.png

寫(xiě)入方式

增量寫(xiě)入:
不管key是否重復(fù)朴则,直接將數(shù)據(jù)追加在前數(shù)據(jù)后。

如果不斷 增量 追加內(nèi)容钓简,文件越來(lái)越大乌妒,怎么辦汹想?

全量寫(xiě)入:
當(dāng)文件大小不夠,這時(shí)候需要全量寫(xiě)入撤蚊。將數(shù)據(jù)去掉重復(fù)key后古掏,如果文件大小滿足寫(xiě)入的數(shù)據(jù)大小,則可以直接更新全量寫(xiě)入侦啸,否則需要擴(kuò)容槽唾。(在擴(kuò)容時(shí)根據(jù)平均每個(gè)K-V大小計(jì)算未來(lái)可能需要的文件大小進(jìn)行擴(kuò)容,防止經(jīng)常性的全量寫(xiě)入)

擴(kuò)容

擴(kuò)容非常簡(jiǎn)單光涂,只需要重新設(shè)定文件大小庞萍,然后重新mmap映射即可

//重新設(shè)定文件大小
ftruncate(m_fd, m_size);
//解除映射
munmap(m_ptr, oldSize);
//重新映射
m_ptr = (int8_t *) mmap(m_ptr, m_size, PROT_READ | PROT_WRITE, MAP_SHARED, m_fd, 0);

存儲(chǔ)的小例子

010 編輯器查看截圖,總長(zhǎng)度-》key長(zhǎng)度-》value長(zhǎng)度

沒(méi)有xml 的冗余數(shù)據(jù)忘闻,更小钝计,更方便增量更新∑爰眩總長(zhǎng)度改下私恬,k-v 在后面追加就可以了。內(nèi)存中的map集合中永遠(yuǎn)是最新的數(shù)據(jù)重虑。

Protobuf 變長(zhǎng)編碼 例子

編碼65280-》

1111 1111 0000 0000

取低七位:000 0000践付,最高位補(bǔ)1(表示還需要下一個(gè)字節(jié))

1000 0000 -》寫(xiě)出

右移7位:1111 1111 0

取低七位:111 1110秦士,最高位補(bǔ)1

1111 1110 -》 寫(xiě)出
右移7位:11

小于0x7f缺厉,最高位不需要設(shè)置為1

0000 0011 -》寫(xiě)出

解析:

1000 0000
1111 1110
0000 0011

拿后7位,7個(gè)0
000 0000高位是1需要繼續(xù)獲取
再次拿后7位
111 1110 高位是1需要繼續(xù)獲取拼接 111 1110 000 0000
再次拿后7位
000 0011 高位0隧土,不許繼續(xù)提针,直接拼接去掉頭部無(wú)用0
000 0011111 1110 000 0000

最后整理之后
1111 1111 0000 0000

被編譯成了3個(gè)字節(jié),定長(zhǎng)編碼應(yīng)該是4個(gè)字節(jié)曹傀,節(jié)省1個(gè)字節(jié)


1頁(yè)4096 字節(jié)辐脖,linux 按照頁(yè)方式存儲(chǔ),超過(guò)1頁(yè)數(shù)據(jù)量發(fā)生頁(yè)中斷皆愉。

參考MMKV 文檔

官方項(xiàng)目MMKV project

下一篇文章 MMKV(二) 基礎(chǔ)知識(shí)和核心流程

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
禁止轉(zhuǎn)載嗜价,如需轉(zhuǎn)載請(qǐng)通過(guò)簡(jiǎn)信或評(píng)論聯(lián)系作者。
  • 序言:七十年代末幕庐,一起剝皮案震驚了整個(gè)濱河市久锥,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌异剥,老刑警劉巖瑟由,帶你破解...
    沈念sama閱讀 218,525評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異冤寿,居然都是意外死亡歹苦,警方通過(guò)查閱死者的電腦和手機(jī)青伤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)殴瘦,“玉大人狠角,你說(shuō)我怎么就攤上這事◎揭福” “怎么了擎厢?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,862評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)辣吃。 經(jīng)常有香客問(wèn)我动遭,道長(zhǎng),這世上最難降的妖魔是什么神得? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,728評(píng)論 1 294
  • 正文 為了忘掉前任厘惦,我火速辦了婚禮,結(jié)果婚禮上哩簿,老公的妹妹穿的比我還像新娘宵蕉。我一直安慰自己,他們只是感情好节榜,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,743評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布羡玛。 她就那樣靜靜地躺著,像睡著了一般宗苍。 火紅的嫁衣襯著肌膚如雪稼稿。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,590評(píng)論 1 305
  • 那天讳窟,我揣著相機(jī)與錄音让歼,去河邊找鬼。 笑死丽啡,一個(gè)胖子當(dāng)著我的面吹牛谋右,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播补箍,決...
    沈念sama閱讀 40,330評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼改执,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了坑雅?” 一聲冷哼從身側(cè)響起辈挂,我...
    開(kāi)封第一講書(shū)人閱讀 39,244評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎霞丧,沒(méi)想到半個(gè)月后呢岗,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,693評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,885評(píng)論 3 336
  • 正文 我和宋清朗相戀三年后豫,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了悉尾。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,001評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡挫酿,死狀恐怖构眯,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情早龟,我是刑警寧澤惫霸,帶...
    沈念sama閱讀 35,723評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站葱弟,受9級(jí)特大地震影響壹店,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜芝加,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,343評(píng)論 3 330
  • 文/蒙蒙 一硅卢、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧藏杖,春花似錦将塑、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,919評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至来吩,卻和暖如春敢辩,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背误褪。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,042評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工责鳍, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人兽间。 一個(gè)月前我還...
    沈念sama閱讀 48,191評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像正塌,于是被迫代替她去往敵國(guó)和親嘀略。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,955評(píng)論 2 355