mmkv 己見

引言

最近微信開源了 mmkv,以前曾經深爲 android 跨進程數據共享和通訊所困惑,用 contextprovider 裏面 sharedpreference,也曾經考慮過用文件讀寫來實現,但是 Java 端對文件讀寫跨進程操做實在是沒有很大可操做餘地,ndk寫的話又太耗時並且沒法保障測試性能等等問題。如今開源的 mmkv 正好彌補來這一塊空缺,並且結果微信檢驗,在性能和安全方面感受仍是比較靠譜的。android

詳解

跨進程數據共享主要有如下問題:c++

  1. 多進程數據如何保持數據一致性即寫更新,讀的都是最新的
  2. 如何保證穩定性和高效性,下降性能消耗

mmkv 最初的設計並非爲了考慮多進程狀況。主要是提升了 key-value 存儲的性能。緩存

  1. 使用 protobuf 二進制來存儲數據。做爲高效數據壓縮編碼方式,無疑提升了寫入和讀取性能
  2. 增量更新。經過將修改數據寫在後面,等待內存滿了以後觸發重整進行整理。提升了修改操做的性能,不須要再去查詢舊數據進行修改。固然在不斷觸發內存重整的狀況下會大大損耗性能(回到),但通常狀況下這明顯是低機率事件.且存儲限制會指數增加。
  3. mmap 文件映射內存,省去一次拷貝的時機。

而以後考慮 android 多進程的狀況,針對多進程須要考慮狀況:安全

  1. 指示器。拿文件前面幾個字節做爲當前寫的位置。多進程模式下,每一個進程讀寫時候都要檢查一下當前和內存是否一致。不一致則須要讀取新寫的。
  2. 鎖。使用了文件讀寫鎖,在外部作了封裝,能夠更好支持。
  3. 增長了 Ashmem 的支持。

使用

  1. 使用簡單,最好直接使用 static 的依賴,由於普通的依賴會添加 libc++_shared.so ,會致使包比 static 大2倍以上
implementation 'com.tencent:mmkv-static:1.0.19'
複製代碼
  1. 性能測試,多進程和單進程性能相差很小。1000 次寫穩定在幾十毫秒,在新機器上會達到20、30毫秒內。1000 次讀能穩定在10毫秒左右。偶爾可能會有波動。整體看性能比讀寫 file 高10倍以上,比 sharedference 寫高百倍(由於 sharedference 就算使用 apply,在最後未完成也要補回來),讀由於 sharedference 是內存操做因此相差不大。
  2. 由於 mmkv 在 native 層作了較多緩存,因此在使用是能夠不須要考慮建立性能單例等等問題

注意事項

  1. 使用 file 沒有特別注意的地方,可是要注意本身不要每次都添加很大的數據,很頻繁觸發內存重整,效率會很低。bash

  2. 使用 Ashmem 的話,有不少注意地方。能夠的話能不用就不用,使用 file + 邏輯來代替微信

    1. 內部實現實際使用了 MMKVContentProvider 來傳遞文件描述符
    2. 在 X86 某些機型上很容易 anr
    3. 若是 MMKVContentProvider 所在進程掛了從新啓動,會致使 ashmem 生成新的,和其它還存在進程不一致。
  3. 由於 mmkv 沒法保障原子性操做。相似樂觀鎖的須要本身實現app

  4. mmkv 採用 mmap,實際上 binder 內部實現也是使用 mmap。因此不須要過多擔憂內部穩定性ide

相關文章
相關標籤/搜索