• 李杰
    2019-01-08
    老师您好!
    最近正打算利用MMKV替换SharedPreferences,研读了一下MMKV的源代码,发现他们在内存重组的时候是直接在原始文件中写重组过后的数据,并且重组完成之后没有sync, 感觉这样会有很大的风险。虽说mmap利用操作系统的机制来保证即使进程被杀,也能写数据, 但首先得保证把所有要写的数据写进mmap映射的内存中,如果在写完成之前进程就已经被杀了,那就有可能出现mmap中的数据是错误的,即使完成了写mmap内存,如果在操作系统将数据写入硬盘前突然关机,那也有可能丢失数据,造成最终的数据损坏。
    而SharedPreferences的写操作,首先是将原始文件备份,再写入所有数据,只有写入成功了,并且通过sync完成落盘后,才会将Backup文件删除。如果在写入过程中进程被杀,或者关机,进程再次起来的时候发现存在Backup文件,就将Backup文件重命名为原始文件,原本未完成写入的文件就直接丢弃来,这样最多也就是未完成写入的数据丢失,文件是不会损坏的,所以可以认为SharedPreferences的写入在单进程中是安全的,也正是因为back的机制,导致多进程可能会丢失新写入的数据。
    从MMKV的github上看到数据有效性的说明,在ios每天存在超过70万次的数据校验失败,是不是就是写数据实际是不安全的导致的呢?对MMKV和SharedPreferences的理解可能不对,请老师帮忙解答一下,谢谢!
    展开

    作者回复: 赞,研究的挺细的,大部分都对。不过mmkv有考虑这点做了crc检验,文件损坏之后支持recover模式,从文件中尽力而为的修复数据

    
     24
  • 薯条
    2019-10-05
    打卡,一直以来,想用probuff作为数据传输,可是原生的操作有点麻烦,有幸得知mmkv库,收获
    
     2
  • 李杰
    2019-01-08
    老师您好!
    针对mmkv的recover模式,也正是我们担心的一个点。从mmkv源码来看,在crc校验失败后默认选择丢弃数据。recover模式作为一个可选模式,也没有看到有什么恢复数据的措施,只是仍然强行decode数据,这样的话理论上decode出来的数据就可能是错误的,不知道是不是哪里疏漏了或是理解有问题。

    作者回复: 因为用了pb的结构已经二进制了,如果某一行写出问题,应该是decode失败的。

    不过这里可能的确有优化的空间,可能文件头上面可以记住上一次检验成功的行数。

    
     2
  • 书虫
    2019-02-26
    老师,当应用收到系统广播,或者被调用 onPause 等一些时机,系统会强制把所有的 SharedPreferences 对象数据落地到磁盘,这说法依据的在哪里?

    作者回复: 可以看看源码,ActivityThread

    
     1
  • 薯条
    2019-10-05
    打卡,在职业生涯中,的确遇到Sh 保存数据 卡顿的问题。以后尽量使用MMKV框架
    
    
  • 大土豆
    2019-05-04
    之前看专栏的时候,这个部分跳过了,结果我负责的App出现了严重的卡顿卡顿,BlockCanery查了半天,发现是sp的锅,性能差倒是其次,关键是Activity的生命周期中需要处理sp的任务,造成了很严重的卡顿,我的思路是一部分不需要持久化的数据改成内存缓存,还有一部分需要持久化的数据改成mmkv

    作者回复: SP使用不当的确是比较多团队遇到的问题,很多人无论大小的数据都使用sp

     1
    
  • HI
    2019-01-14
    谢谢,长见识了
    
    
  • 东方
    2019-01-10
    张老师,今天跑了mmkv的demo,发现文件内容是append形式,不会覆盖前面的key,导致文件内容越来越大。

    作者回复: 在达到一定大小的时候会做自动合并,这块可以看看源码的介绍

     1
    
我们在线,来聊聊吧