微信MMKV原理與實現(二) 檔案資料結構

2021-10-25 12:40:36 字數 3038 閱讀 2339

說到輕量級的資料持久化,大家最先想到的就是sharedpreferences(以下簡稱sp)了,sp儲存方式為xml,直接使用i/o流進行檔案的讀寫,這就形成了乙個弊端:每次寫入或修改都需要替換掉原來的資料,並將所有資料 重新寫入檔案。可想而知,如果乙個sp檔案的內容過多,那麼再寫入的時候會造成卡頓,甚至會有 anr的風險。

虛擬記憶體被作業系統劃分成兩塊:使用者空間和核心空間,使用者空間是使用者程式**執行的地方,核心空間是核心**執行的地方。為了安全,它們是隔離的,即使使用者的程式崩潰了,核心也不受影響。

1、呼叫write,告訴核心需要寫入資料的開始位址與長度

2、核心將資料拷貝到核心快取

3、由作業系統呼叫,將資料拷貝到磁碟,完成寫入

可見,將資料寫入檔案需要將資料拷貝兩次,再寫入到檔案中,如果資料量過大,也會有很大的效能損耗。

對檔案進行對映,會在程序的虛擬記憶體分配位址空間,建立對映關係。實現這樣的對映關係後,就可以採用指標的方式讀寫操作這一段記憶體,而系統會自動回寫到對應的檔案磁碟上。

下面來對比一下sp可mmkv同事儲存1000條資料的耗時:

protobuf 是google開源的乙個序列化框架,類似xml,json,最大的特點是基於二進位制,比傳統的xml表示同樣一段內容要短小得多。

mmkv正式基於protobuf協議進行資料儲存,儲存方式為增量更新,也就是不需要每次修改資料都要重新將所有資料寫入檔案了。

protobuf是二進位制儲存格式,第一位代表的是key和value的總長度,後面是key長度->key, value長度->value。。。。。 依次排列,可以用二進位制檢視工具來看一下:

為了方便理解,這裡拿整型編碼舉例:

1個位元組儲存7位資料,第1位為標誌位

如果寫入的資料 <= 0x7f 那麼使用7位即1個位元組表示,完成編碼

如果寫入的資料 > 0x7f 那麼先記錄低7位資料,並將最高位設為1,繼續執行判斷

16進製制

0x7f

10進製

1272進製

以上**就是整型的寫入方式。

為了更好的說明編碼和解碼的原理,我們拿乙個整型來進行計算: 318242

編碼首先將318242進行二進位制轉換

編碼318242 -》

0100 1101 1011 0010 0010 (步1)

大於0x7f,取最低7位,最高位補1:

1010 0010 ------------》寫出到檔案

將步1的資料右移7位

0000 0000 1001 1011 0110 (步2)

再取低7位,最高位補1

1011 0110 ------------》寫出到檔案

再將步2的資料右移7位

0000 0000 0000 0001 0011(步3)

再取低7位,最高位補1

1001 0011 ------------》寫出到檔案

再將步3的資料右移7位

0000 0000 0000 0000 0000 (步4)

再取低7位,因為這7位小於0x7f,不需要補1,直接寫出

0000 0000 ------------》寫出到檔案

經過以上8個步驟,protobuf就為318242編碼完成了。

解碼拿到上面寫入的幾組資料:

1010 0010

1011 0110

1001 0011

0000 0000

然後從後面往前拼接:(注意一下,因為前3個資料只有後7位是有效資料,拼接時要去掉首位)

1)將4拼接到3前面:

0000 0000 001 0011

2)再將上面的資料拼接到2前面:

0000 0000 001 0011 011 0110

3)再拼接到1前面:

0000 0000 001 0011 011 0110 010 0010

去除無效位:

0 001 0011 011 0110 010 0010

這樣就得到了原二進位製碼(0100 1101 1011 0010 0010)。

任何事情都是有兩面性的,mmkv也有它的缺點。

上面簡單的模擬了一下mmkv儲存資料的流程。由上可知,linux採用了分頁來管理記憶體,存入資料先要建立乙個檔案,並要給這個檔案分配乙個固定的大小。如果存入了乙個很小的資料,那麼這個檔案其餘的記憶體就會被浪費。相反如果存入的資料比檔案大,就需要動態擴容。

不過具體情況要具體分析,大多數情況是優大於弊的!

微信MMKV原始碼分析 二 mmap對映

系列文章 void mmkv loadfromfile m metainfo.read m metafile.getmemory o rdwr 讀 寫開啟 o creat 若此檔案不存在則建立它。使用此選擇項時,需同時說明第三個引數mode,用其說明該新檔案的訪問許可權位。s irwxu 模式標誌 ...

springboot與微信開發(二)

上一節講述了配置介面,這次看一下關注 接收和傳送訊息。我們先看效果圖 在上一次的controller裡面加上 model裡面則為 public class basemessage public string gettousername public void settousername string...

微信語音技術原理 微信語音電話是如何實現的?

貼個我之前的回答吧,乙個原理 但是,技術不一定換得來市場,未來幾何?仍然是個未知數。乍一看,兩者沒有什麼區別。volte就是無線語音技術的下一代,看起來很像無線連線的voip業務。一定程度上說,它就是的,將語音通過ip包來傳輸。但從技術上說,它又不完全是的。首先,要了解乙個區別是,volte是基於i...