首页 > 代码库 > MemoryCache
MemoryCache
MemoryCache模块是负责网页加载的一个庞大机制,loader的一部分。这里(https://www.webkit.org/blog/427/webkit-page-cache-i-the-basics/)可以了解更多。本文只谈Memory Cache,以及它内部的一些组件,不涉及到与loader的交互。
你可以在MemoryCache.h中找到关于MemoryCache是什么以及它的目的的简单描述。
该缓存保留网页用到的子资源:图片,js, css, 等等。它保持一个灵活但有限的dead resource窗口,窗口大小随着live resource的加载扩大/缩小。下面是一个缓存随时间增长的例子,该例子中,最小的dead resource capacity是25%, 最大的dead resource capacity是50%。
|-----| Dead: - |----------| Live: + --|----------| Cache boundary: | (objects outside this mark have been evicted) --|----------++++++++++| -------|-----+++++++++++++++| -------|-----+++++++++++++++|+++++
如果shouldMakeResourcePurgeableOnEviction返回true,缓存变化的方式如下:
1 缓存中的dead resources 被保留在non-purgeable内存中
2 当我们裁剪(prune)dead resources时, 不是真的释放内存, 而是把它们的内存标记为purgeable直到内核重新申请该内存。
通过把裁剪的dead resource保留在“非纯净”常驻内存中,我们较少了因系统回收内存而不得不重新加载资源的可能性(比如当用户点击后退时)
而且通过使用purgeable memory存储无限多个资源对象,我们能够使用机器的所有内存。
purgeable/non-purgeable内存到底是什么意思呢?有的操作系统允许标记内存为可清除。意思是,从标记时刻开始,里面的内存有可能在任何时候被清除,而且不会通知应用程序。因此,当应用程序向系统请求资源时,可能被告知已被清除。这严重影响了对象的生命周期管理:
- 这类内存不允许存储依赖于虚构函数的对象
- 内存的所有权/引用永远不应该传给那些不把内存当做“特殊对象”的模块
- 众所周知并广泛使用的对象生命周期管理方法(比如智能指针)不适合存储在purgeable 内存中的对象
了解了在purgeable 内存中存储对象的副作用之后,我们来看看memory cache的构成:
MemoryCache 类
这个类用于存储和管理对象的生命周期。存储的资源可能是活动的也可能是非活动的。非活动资源是指没有网页引用的资源。反之,活动资源是指至少有一个网页引用的资源。
MemoryCache client通过三个值控制对RAM的使用:
- min dead bytes - prune时dead resources 的最小size
- max dead bytes - prune时dead resources 的最大size
- total capacity bytes - 活动资源和非活动资源能够使用的容量
不用惊慌。Total capacity并不决定Webkit保存在内存中的资源size上限,因此不会出现只保留加载网页一半的情况。它只是一个决定何时进行裁剪的阀值。prune又是怎么回事呢?首先,我们来解释什么是活动资源和非活动资源。当一个资源被下载时,作为raw data存储在内存(可能是图片,css, js等)。Raw data需要被解码后才能使用。资源被解码时,开始变成活动资源(意味着有CachedResourceClient需要用到它)。最后一个CachedResourceClient不在使用它时就变成非活动资源。活动资源和非活动资源都可能包含解码数据,占据着内存,这是不必要的。因此,提供了prune()方法。首先,MemoryCache将会prune非活动资源(满足dead resource size的最大最小限制),然后逐个裁剪活动资源直到所有资源的size小于total capacity。
Prune过程提供了一个机制来降低内存消耗。在文章已经提到这一古雅技术 -- purgeable memory。CachedResource能够移动存储的raw data到一个叫做PurgeableBuffer的特殊缓冲区中。Evict将会把一个资源从MemoryCache的内部结构中移除,之后恢复它的唯一方法只能是通过相应的ResourceRequest。
LRU lists
- MemoryCache在三个结构中保持对资源的引用
- m_resources - 一个基于LRU的map,保存了所有的在缓存中的资源
- m_allResources - 固定大小为32的LRU列表Vector。一个资源基于访问次数被分配在合适的列表中。Prune将从最久未使用的资源开始淘汰。
- m_liveDecodedResource - 含有解码数据的live resource。如果存储的数据超过了总的容量限制,MemoryCache将逐个删除解码数据,直到释放计划释放的空间,或者没有更多冗余数据可以释放。
原文:https://trac.webkit.org/wiki/MemoryCache#no1
MemoryCache
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。