1,MMKV,JetPack DataStore和Sp对比
DataStore:是一种数据存储解决方案,允许您使用协议缓冲区存储键值对或类型化对象。DataStore 使用 Kotlin 协程和 Flow 以异步、一致的事务方式存储数据,主要从稳定性考虑。
MMKV:是基于 mmap 内存映射的 key-value 组件,底层序列化 / 反序列化使用 protobuf 实现,性能高,稳定性强。从 2015 年中至今,在 iOS 微信上使用已有近 3 年,其性能和稳定性经过了时间的验证
SP:在contextImpl中获取SP的方法getSharePerference时候可以看到是new了一个ArrayMap ArrayMap和HashMap的区别,sp使用不当可能导致启动速度变慢(当数据比较大的时候,在调用get方法时,如果数据没有加载完,会导致在线程上加锁,只有当数据加载完成之后,才能继续去执行get方法),如果咋onDraw中频繁的调用sp.edit()会出现卡顿,在Edit()方法中回去频繁的创建对象,GC会频繁的运行回收这些临时map,会导致卡顿
ArrayMap是一个<key,value>映射的数据结构,它设计上更多的是考虑内存的优化,内部是使用两个数组进行数据存储,一个数组记录key的hash值,另外一个数组记录Value值,它和SparseArray一样,也会对key使用二分法进行从小到大排序,在添加、删除、查找数据的时候都是先使用二分查找法得到相应的index,然后通过index来进行添加、查找、删除等操作,所以,应用场景和SparseArray的一样,如果在数据量比较大的情况下,那么它的性能将退化至少50%。
HashMap:内部是使用一个默认容量为16的数据来存储数据的,而数组中的每一个元素又是一个链表的头节点或者红黑树的根节点,所有更准确的说hashMap内部是一个数据+链表+红黑树的结构。
SP中commit和apply的区别
commit方法有返回值,可以知道提交的数据是否成功,是同步提交,如果数据量大,CPU比较忙,在提交时,会出现ANR
apply没有返回值,它的提交是一个异步提交,apply提交数据是会创建一个Runnable任务,会把任务添加到QueueWork队列中排队执行
Activity跳转的时候 AMS ———》 Bindler———》ActivityThread#ApplicationThread———》XXXX ————》handler---》调用 onCreat方法
在执行onCreat方法时会去执行handlePauseActivity()方法中QueueWork.waitToFinsh(),等待QueueWork中的任务执行完,才能完成跳转,所以虽然apply是异步执行的,但是最终会调用QueueWork的这个方法,因此也有可能导致ANR
2,SP的原理分析
3,MMAP在Android中的使用
传统IO:虚拟内存被是操作系统分为两块,内核空间和用户空间,用户空间是用户代码运行的地方,内核空间内核代码运行的地方,内核空间是所有程序共享的,就算程序奔溃了,内核空间也不受影响。
写文件流程:调用write向内核发起系统,上下文从用户态切换到内核态; CPU将用户缓冲区的数据copy到内核缓冲区(CPU拷贝);CPU利用DMA控制器将数据从内核缓冲去拷贝到磁盘缓冲区进行数据传输(DMA拷贝);上下文从内核态切换到用户态,write系统调用返回
MMAP:linux通过将一个虚拟的内存空间和一个磁盘的对象关联起来,以初始化这个虚拟空间的内容,这个过程称为内核映射(Memory Mapping)
对文件进行mmap操作,会在进程的虚拟内存分配地址空间;实现这样的关系后,就可以采用指针的方式读写操作这一段内存,而系统会自动回写到对应的文件磁盘上
MMAP的优势:对文件的读写操作只需要磁盘到用户主存的一次拷贝过程,减少了数据的操作过程,提高了文件操作的效率;MMAP使用逻辑内存对磁盘进行映射,操作内存就相当于操作文件,不需要开启线程,操作MMAP的速度和操作内存的速度一样快;MMAP提供了一盘可供随时写入的内存块,app只管往里面写数据,由于系统内存不足退出时会回写文件。