内存缓存
缓存分为2类,内存缓存和磁盘缓存,今天说的是内存缓存。
内存缓存实现很多种方式,最简单的是就是用NSMutableDictionary来实现,性能也是最好的,但是它不是线程安全的,而且也没有存到一定程度删除的机制。
内存缓存实现的比较好的有苹果官方的NSCache,ibireme的YYMemoryCache,Pinterest的PINMemoryCache。他们都是线程安全的,也都提供了数量限制、总容量限制、内存警告清空缓存等功能。
这是ibireme提供的他们性能对比图
NSCache
NSCache 是苹果提供的一个简单的内存缓存,它有着和NSDictionary 类似的 API,不同点是它是线程安全的,并且不会 retain key。NSCache 底层并没有用 NSDictionary 等已有的类,而是直接调用了 libcache.dylib,其中线程安全是由 pthread_mutex 完成的。还有一点就是它的读取性能要比存取性能要好。
NSCache 有好多知名的三方库在用,比如SDWebImage、AFNetworking等。网上有很多关于NSCache的用法教程,这里就不多介绍。
推荐一篇关于它用法的博客
YYMemoryCache
YYMemoryCache是ibireme开源的内存缓存库,它的性能是比较好的,今天主要讲一下它的实现。
特征
- LRU淘汰算法
- 收到内存警告时可精准控制行为
- 对象数量限制, 总容量限制, 存活时间限制
- 查询和插入时, 并不是通过遍历双向链表, 而是使用字典hash表快速查找到指定结点, 保证效率
主要手段
- CFMutableDictionaryRef来实现数据的实际存储;
- 使用OSSpinLockLock来保证线程的安全 (之后改为pthread_mutex_lock)
- 使用_YYLinkedMapNode和_YYLinkedMap来组织数据的存储结构
- 使用YYMemoryCache来组织对数据的各种操作
LRU淘汰算法也可以叫做最近最少使用,看下面这张图比较容易理解。
image
它的实现主要有3步:
1、新数据插入到链表头部;
2、每当缓存命中(即缓存数据被访问),则将数据移到链表头部;
3、当链表满的时候,将链表尾部的数据丢弃。
YYMemoryCache里面用双向链表和NSMutableDictionry的方式来实现LRU淘汰算法。
关于双向链表可以看下面这个博客
http://blog.csdn.net/wangzhen209/article/details/8180462
网友评论