說到輕量級的資料持久化,大家最先想到的就是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...