49-内存管理中的cache

原创 2016年04月26日 12:29:38

49-内存管理中的cache

在维基百科中有这样一段描述: 凡是位于速度相差较大的两种硬件之间的,用于协调两者数据传输速度差异的结构,均可称之为Cache。 从最初始的处理器与内存间的Cache开始,都是为了让数据访问的速度适应CPU的处理速度, 其基于的原理是内存中“程序执行与数据访问的局域性行为”。 同样PHP内存管理中的缓存也是基于“程序执行与数据访问的局域性行为”的原理。 引入缓存,就是为了减少小块内存块的查询次数,为最近访问的数据提供更快的访问方式。

PHP将缓存添加到内存管理机制中做了如下一些操作:

  • 标识缓存和缓存的大小限制,即何时使用缓存,在某些情况下可以以最少的修改禁用掉缓存
  • 缓存的存储结构,即缓存的存放位置、结构和存放的逻辑
  • 初始化缓存
  • 获取缓存中内容
  • 写入缓存
  • 释放缓存或者清空缓存列表

首先我们看标识缓存和缓存的大小限制,在PHP内核中,是否使用缓存的标识是宏ZEND_MM_CACHE(Zend/zend_alloc.c 400行), 缓存的大小限制与size_t结构大小有关,假设size_t占4位,则默认情况下,PHP内核给PHP内存管理的限制是128K(32 * 4 * 1024)。 如下所示代码:

#define ZEND_MM_NUM_BUCKETS (sizeof(size_t) << 3)

#define ZEND_MM_CACHE 1
#define ZEND_MM_CACHE_SIZE (ZEND_MM_NUM_BUCKETS * 4 * 1024)

如果在某些应用下需要禁用缓存,则将ZEND_MM_CACHE宏设置为0,重新编译PHP即可。 为了实现这个一处修改所有地方都生效的功能,则在每个需要调用缓存的地方在编译时都会判断ZEND_MM_CACHE是否定义为1。

如果我们启用了缓存,则在堆层结构中增加了两个字段:

struct _zend_mm_heap {

#if ZEND_MM_CACHE
    unsigned int        cached; //  已缓存元素使用内存的总大小
    zend_mm_free_block *cache[ZEND_MM_NUM_BUCKETS]; //  存放被缓存的块
#endif

如上所示,cached表示已缓存元素使用内存的总大小,zend_mm_free_block结构的数组装载被缓存的块。 在初始化内存管理时,会调用zend_mm_init函数。在这个函数中,当缓存启用时会初始化上面所说的两个字段,如下所示:

#if ZEND_MM_CACHE
    heap->cached = 0;
    memset(heap->cache, 0, sizeof(heap->cache));
#endif

程序会初始化已缓存元素的总大小为0,并给存放缓存块的数组分配内存。 初始化之后,如果外部调用需要PHP内核分配内存,此时可能会调用缓存, 之所以是可能是因为它有一个前提条件,即所有的缓存都只用于小于的内存块的申请。 所谓小块的内存块是其真实大小小于ZEND_MM_MAX_SMALL_SIZE(272)的。 比如,在缓存启用的情况下,我们申请一个100Byte的内存块,则PHP内核会首先判断其真实大小, 并进入小块内存分配的流程,在此流程中程序会先判断对应大小的块索引是否存在,如果存在则直接从缓存中返回, 否则继续走常规的分配流程。

当用户释放内存块空间时,程序最终会调用_zend_mm_free_int函数。在此函数中,如果启用了缓存并且所释放的是小块内存, 并且已分配的缓存大小小于缓存限制大小时,程序会将释放的块放到缓存列表中。如下代码:

#if ZEND_MM_CACHE
    if (EXPECTED(ZEND_MM_SMALL_SIZE(size)) && EXPECTED(heap->cached < ZEND_MM_CACHE_SIZE)) {
        size_t index = ZEND_MM_BUCKET_INDEX(size);
        zend_mm_free_block **cache = &heap->cache[index];

        ((zend_mm_free_block*)mm_block)->prev_free_block = *cache;
        *cache = (zend_mm_free_block*)mm_block;
        heap->cached += size;
        ZEND_MM_SET_MAGIC(mm_block, MEM_BLOCK_CACHED);
#if ZEND_MM_CACHE_STAT
        if (++heap->cache_stat[index].count > heap->cache_stat[index].max_count) {
            heap->cache_stat[index].max_count = heap->cache_stat[index].count;
        }
#endif
        return;
    }
#endif

当堆的内存溢出时,程序会调用zend_mm_free_cache释放缓存中。整个释放的过程是一个遍历数组, 对于每个数组的元素程序都遍历其所在链表中在自己之前的元素,执行合并内存操作,减少堆结构中缓存计量数字。 具体实现参见Zend/zend_alloc.c的909行。

在上面的一些零碎的代码块中我们有看到在ZEND_MM_CACHE宏出现时经常会出现ZEND_MM_CACHE_STAT宏。 这个宏是标记是否启用缓存统计功能,默认情况下为不启用。缓存统计功能也有对应的存储结构,在分配,释放缓存中的值时, 缓存统计功能都会有相应的实现。

49-多态的概念和意义

1、函数重写(override)回顾2、多态的概念和意义3、4、#include #include using namespace std;class Parent { public: vi...
  • zy13270867781
  • zy13270867781
  • 2017年10月30日 18:03
  • 60

49-玻璃效果菜单

效果演示: 实现代码: body{ margin:0; margin-top:20px; } ul#menu { font...
  • u010653050
  • u010653050
  • 2013年10月14日 20:00
  • 736

49-进程通信初步

错综复杂的信号专题终于结束,能写到这里,感觉真不容易,甚至有点小激动,因为接下来进入进程间通信这个老生常谈的大专题。希望能有信心写好,因为我自己也有很多地方没有弄清晰,希望借此笔记来提升一下自己。进程...
  • q1007729991
  • q1007729991
  • 2016年12月29日 21:46
  • 582

cache 的设计与实现

本文整理自一下两篇博客:http://my.oschina.net/ScottYang/blog/298727http://my.oschina.net/u/866190/blog/188712 C...
  • zhushuai1221
  • zhushuai1221
  • 2016年07月14日 13:58
  • 550

Cache的组成结构

在一个Cache中包含多行多列,存在若干类组成方式。在处理器体系结构的历史上,曾出现过更多的的组成结构,最后剩余下来的是我们耳熟能详的Set-Associative组成结构。这种结构在现代处理器微架构...
  • anjiashuai521
  • anjiashuai521
  • 2014年03月09日 14:50
  • 1176

NYOJ:49-开心的小明

开心的小明 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描述 小明今天很开心,家里购置的新房就要领钥匙了,新房里有一间他自己专用的很宽敞的房间。更让他高兴的是,妈妈...
  • m0_37306360
  • m0_37306360
  • 2017年06月23日 01:02
  • 60

cache 写回策略

写回策略主要分两种: 写回(write back )和 写通(write through)1. write back只有在一个cache行被选中替换回主存时,如果cache 行的数据是修改过的(di...
  • dark5669
  • dark5669
  • 2016年12月27日 15:15
  • 2066

深入研读Cache存储的计算

假设某个计算机的主存地址空间是256MB,按照字节编址,其数据Cache有8行,行长有64B.从这道题目里要好好领悟Cache策略的优美之处。1)不考虑用于Cache的一致性维护位和替换算法控制位,并...
  • u011240016
  • u011240016
  • 2016年09月28日 14:33
  • 1879

基于直接相联映象方式的Cache设计

基于直接相联映象方式的Cache设计
  • Quinze_Lee
  • Quinze_Lee
  • 2016年06月03日 20:42
  • 3777

关于Cache的计算

关于Cache的计算
  • EckoTan
  • EckoTan
  • 2015年07月05日 17:17
  • 2823
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:49-内存管理中的cache
举报原因:
原因补充:

(最多只允许输入30个字)