基本数据结构

5.1.1 基本数据结构

chunk由512个page组成,其中第一个page用于保存chunk结构,剩下的511个page用于内存分配,page主要用于Large、Small两种内存的分配;heap是表示内存池的一个结构,它是最主要的一个结构,用于管理上面三种内存的分配,Zend中只有一个heap结构。

struct _zend_mm_heap {
#if ZEND_MM_STAT
    size_t             size; //当前已用内存数
    size_t             peak; //内存单次申请的峰值
#endif
    zend_mm_free_slot *free_slot[ZEND_MM_BINS]; // 小内存分配的可用位置链表,ZEND_MM_BINS等于30,即此数组表示的是各种大小内存对应的链表头部
    ...

    zend_mm_huge_list *huge_list;               //大内存链表

    zend_mm_chunk     *main_chunk;              //指向chunk链表头部
    zend_mm_chunk     *cached_chunks;           //缓存的chunk链表
    int                chunks_count;            //已分配chunk数
    int                peak_chunks_count;       //当前request使用chunk峰值
    int                cached_chunks_count;     //缓存的chunk数
    double             avg_chunks_count;        //chunk使用均值,每次请求结束后会根据peak_chunks_count重新计算:(avg_chunks_count+peak_chunks_count)/2.0
}

struct _zend_mm_chunk {
    zend_mm_heap      *heap; //指向heap
    zend_mm_chunk     *next; //指向下一个chunk
    zend_mm_chunk     *prev; //指向上一个chunk
    int                free_pages; //当前chunk的剩余page数
    int                free_tail;               /* number of free pages at the end of chunk */
    int                num;
    char               reserve[64 - (sizeof(void*) * 3 + sizeof(int) * 3)];
    zend_mm_heap       heap_slot; //heap结构,只有主chunk会用到
    zend_mm_page_map   free_map; //标识各page是否已分配的bitmap数组,总大小512bit,对应page总数,每个page占一个bit位
    zend_mm_page_info  map[ZEND_MM_PAGES]; //各page的信息:当前page使用类型(用于large分配还是small)、占用的page数等
};

//按固定大小切好的small内存槽
struct _zend_mm_free_slot {
    zend_mm_free_slot *next_free_slot;//此指针只有内存未分配时用到,分配后整个结构体转为char使用
};

chunk、page、slot三者的关系:

zend_heap

接下来看下内存池的初始化以及三种内存分配的过程。

联系我们

邮箱 626512443@qq.com
电话 18611320371(微信)
QQ群 235681453

Copyright © 2015-2024

备案号:京ICP备15003423号-3