MemoryCache学习

这里(http://blog.csdn.net/wy5761/article/details/41869599)有对MemoryCache的整体介绍。本文说一说MemoryCache核心的部分。

MemoryCache是webkit加载网页的庞大机制 -- Loader的一部分。Webkit采用了缓存机制,发起一个请求时,请求顺序经过一系列的Cache,在每层都会查找请求对应的资源是否存在,存在就返回。MemoryCache处于最上层。如果请求不在缓存,最终就会到达网络层,发起真正的网络请求,从服务器加载资源。

MemoryCache允许占用的空间有限,而且被频繁使用,它把那些最近使用的资源都保存在内存,以加快网页访问速度。因此,替换算法对MemoryCache的影响很大。命中率是衡量MemoryCache性能的一个最主要指标。MemoryCache的实现基于LRU-SP算法,命中率一般都能达到60 - 70%。

LRU-SP

LRU是应用相当广泛的替换算法,它基于引用局部性原理,应用于大小相同的资源的效果很好。Web资源的size差异很大,从几KB到几百KB。通常,存储小的资源的收益会更大。LRU-SP算法综合考虑了资源的size、引用次数、新旧程度。目的是保留那些最近使用的、size较小的、被引用次数多的资源。它实现的方式是,根据资源的size和引用次数计算一个权值fastLog2(size/accessCount),按权值把资源分配在不同的LRUList中,处于同一个LRUList的资源权值相同。插入新的资源时,插在队头,队头的元素比队尾的优先级高。MemoryCache中是采用了一个固定大小32的LRUList
Vector。根据fastLog2(size/accessCount)计算一个[0, 32)的索引,定位资源应该分配的LRUList。当一个资源的引用次数增多时,可能会更新到更高优先级的LRUList。这样管理资源的目的是有限淘汰哪些相对不重要的资源。

Prune

prune,即裁剪,也就是降低MemoryCache的内存占用。还有个evict的函数,两者是有区别的。evict会把资源从MemoryCache的内部结构中删除,被evict的资源,当要再次恢复时,就必须发起加载请求了。

prune这个过程,首先会prune dead resource,由pruneDeadResourcesToSize函数完成。

先尝试释放资源的解码数据,如果计划完成,则返回,否则进一步evict资源。可以看到它是循环对每一个LRUList来执行这个过程的。从索引最大的LRUList开始,该LRUList存储的资源是size很大,并且引用次数少的资源。对于每一个LRUList,又是从队尾开始遍历,这样做的目的是优先淘汰哪些较久未使用的资源。

prune dead resource 之后,接着prune live resource, 由pruneLiveResourcesToSize这个函数完成。可以看到该函数内部没有调用evict。也就是说,活动资源是不会被从MemoryCache中清除的,这一过程只是试着删除多余的数据(解码数据)。资源再次被用到时,必须重新解码,这相当于以时间换空间。

容量限制

MemoryCache原生代码限制容量为8M,这其实很大了。容量限制并不意味着,MemoryCache不会超过这个容量。它只是定义了进行Prune操作的时机,如果打开的窗口很多的时候,肯定会超过容量限制的。

数据结构

有一个map记录了所有在缓存中的资源;一个带有解码数据的活动资源列表;32个LRUList。

时间: 2024-08-09 00:19:55

MemoryCache学习的相关文章

[爬虫学习笔记]MemoryCache缓存的用法学习

      在完成了DNS解析模块之后,我意识到了DNS缓存机制也很有必要.在Redis,Memcache,和.Net自带的Cache之间,考虑到部署问题,最终选择了后者,之前在学习Web及开发的过程中用过System.Web.Caching.Cache这个类库,但是这次的爬虫程序我打算部署为桌面软件,所以选用了System.Runtime.Caching.MemoryCache(后期如有必要也会加入System.Web.Caching.Cache来适配Web端程序).       Memory

Android-Universal-Image-Loader学习笔记(3)--内存缓存

前面的两篇博客写了文件缓存,现在说说Android-Universal-Image-Loader的内存缓存,该内存缓存涉及到的类如图所示 这些类的继承关系如下图所示: 如同文件缓存一样,内存缓存涉及的接口也有两个:MemoryCacheAware 和MemoryCache,其中MemoryCache只是简单的继承了MemoryCacheAware并没有声明其他的方法.MemoryCacheAware接口的方法如下: @Deprecated public interface MemoryCache

缓存学习小结(一)

(Java)缓存的分为文件缓存或磁盘缓存(disc cache)和内存缓存(memory cache)两种:文件缓存就是把数据存储在本地磁盘上,内存缓存通常是一个map.缓存的作用就是把首次从网络的获取数据保存起来,当再次访问的时候可以直接从缓存中获取数据而不是从网络中重新加载.可以减少系统开销,提高响应速度. 单独使用内存缓存和单独使用文件缓存应用的执行流程如下所示: 内存缓存和文件缓存同时使用的情况下的流程图大致如下所示: 需要注意的是,当从网络加载数据的时候用一个线程或者提供一个线程池来完

android Universal-Image-Loader框架学习

一.Universal-Image-Loader概述:    Android-Universal-Image-Loader是一个开源的图片加载框架,这个项目的目的是提供一个可重复使用的仪器为异步图像加载,缓存和显示.   开源库的特性: (1).多线程下载图片. (2).可通过配置ImageLoader,改变线程池,图片下载器,等等的配置. (3).支持图片的在内存缓存,文件系统缓存或sd卡缓存. (4).支持图片下载的监听. (5).可以较好的控制图片的加载过程,例如在listview滑动时停

Android学习笔记之SoftReference软引用...

PS:其实这一篇和上一篇很类似,都是为了解决内存不足(OOM)这种情况的发生... 学习内容: 1.对象的引用类....   最近也是通过项目中知道了一些东西,涉及到了对象的引用类,对象的引用类分为多种,强引用(其实就是正常的引用),使用SoftReference实现软引用,Weak Reference(弱引用) PhantomRefrence(虚引用)...这三个引用类我只详细的介绍一下SoftReference实现软引用...其他的就一笔带过.... 强引用: Object darker=n

深入理解.NET MemoryCache

摘要 MemoryCache是.Net Framework 4.0开始提供的内存缓存类,使用该类型可以方便的在程序内部缓存数据并对于数据的有效性进行方便的管理,借助该类型可以实现ASP.NET中常用的Cache类的相似功能,并且可以适应更加丰富的使用场景.在使用MemoryCache时常常有各种疑问,数据是怎么组织的?有没有可能用更高效的组织和使用方式?数据超时如何控制?为了知其所以然,本文中对于MemoryCache的原理和实现方式进行了深入分析,同时在分析的过程中学习到了许多业界成熟组件的设

从壹开始前后端分离【 .NET Core2.0 Api + Vue 3.0 + AOP + 分布式】框架之九 || 依赖注入IoC学习 + AOP界面编程初探

代码已上传Github,文末有地址 说接上文,上回说到了<从壹开始前后端分离[ .NET Core2.0 Api + Vue 2.0 + AOP + 分布式]框架之八 || API项目整体搭建 6.3 异步泛型+依赖注入初探>,后来的标题中,我把仓储两个字给去掉了,因为好像大家对这个模式很有不同的看法,嗯~可能还是我学艺不精,没有说到其中的好处,现在在学DDD领域驱动设计相关资料,有了好的灵感再给大家分享吧. 到目前为止我们的项目已经有了基本的雏形,后端其实已经可以搭建自己的接口列表了,框架已

Vue.js学习笔记:属性绑定 v-bind

v-bind  主要用于属性绑定,Vue官方提供了一个简写方式 :bind,例如: <!-- 完整语法 --> <a v-bind:href="url"></a> <!-- 缩写 --> <a :href="url"></a> 绑定HTML Class 一.对象语法: 我们可以给v-bind:class 一个对象,以动态地切换class.注意:v-bind:class指令可以与普通的class特

Java多线程学习(吐血超详细总结)

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 目录(?)[-] 一扩展javalangThread类 二实现javalangRunnable接口 三Thread和Runnable的区别 四线程状态转换 五线程调度 六常用函数说明 使用方式 为什么要用join方法 七常见线程名词解释 八线程同步 九线程数据传递 本文主要讲了java中多线程的使用方法.线程同步.线程数据传递.线程状态及相应的一些线程函数用法.概述等. 首先讲一下进程和线程