mysql常用数据结构介绍(1)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/spb3732/article/details/85089168

mem_root

mysql层通过mem_root管理内存分配,防止频繁分配和释放小内存。

mem_root的定义见include/my_alloc.h:

typedef struct st_mem_root
{
  USED_MEM *free;              空闲链表,分配空间时先检查该链表有没有剩余空间,如果没有,再分配新空间
  USED_MEM *used;             已经分配完成的链表空间,该链表中的数据空间几乎没有剩余可用空间
  USED_MEM *pre_alloc;      预先分配的块
  size_t min_malloc;              如果一个USED_MEM块中可用空间left小于该值,这个块放入used链表中
  size_t block_size;               初始块的大小
  unsigned int block_num;      块的数目
  unsigned int first_block_usage; 空闲链表中第一个块检查的次数,如果超过MAX_BLOCK_USAGE_BEFORE_DROP,该块会被放入used链表中

  void (*error_handler)(void);
} MEM_ROOT;

typedef struct st_used_mem
{                   /* struct for once_alloc (block) */
  struct st_used_mem *next;       /* Next block in use */
  unsigned int    left;           /* memory left in block  */
  unsigned int    size;           /* size of block */
} USED_MEM;

该结构主要有两个链表: free和used。 每个链表使用USED_MEM作为数据节点,数据节点中存有空间总大小和未使用的空间大小。新建一个数据节点时,先添加到free链表中,随着空间的分配,数据节点中未使用空间大小left小于阈值min_malloc,该数据节点添加到used链表中。分配空间时,先从free链表中检查有没有可用的空间,如果没有,再分配新的块。

相关的函数:

init_alloc_root: 初始化mem_root对象。如果pre_alloc_size不为0,预先创建一个数据块,free和pre_alloc指向这个数据块。

alloc_root:从mem_root对象中分配指定大小length的内存。 

                   该函数先检查free链表的首个数据块,如果该数据块连续ALLOC_MAX_BLOCK_USAGE_BEFORE_DROP(10)次不满足分配条件,并且该块小于ALLOC_MAX_BLOCK_TO_DROP(4K),将该块移动到used链表中。

                  依次检查free链表中剩余空间大于length的数据块。如果不存在这样的数据块,新建一个数据块。注意新建数据块的大小如下,可以看到分配的空间大小会趋向于越来越大:

 block_size= mem_root->block_size * (mem_root->block_num >> 2);    缺省大小,block_num每增加4,分配的内存大小增加block_size
    get_size= length+ALIGN_SIZE(sizeof(USED_MEM));    分配请求的空间大小
    get_size= MY_MAX(get_size, block_size);  取最大值

                 修改该数据块的left剩余空间,如果left剩余空间小于min_malloc,加入到used链表的表头。

reset_root_defaults

            该函数设置block_size和pre_alloc块。如果没有符合要求的pre_alloc块,遍历free链表,查找符合要求的数据块,如果发现完全没有使用的数据块,free该块的空间。如果最后没有找到,新建一个符合要求的块。

             

free_root: 清空分配的数据块

      MY_MARK_BLOCKS_FREE: used链表中的数据库合并到free链表中,并且所有数据块中数据清空(left设置为初始块大小)。最终结果:free链表指向所有的数据块,used链表中空。没有向操作系统释放空间

    MY_KEEP_PREALLOC:只保留pre_alloc块,其他块的空间都释放给操作系统。

参考:https://www.cnblogs.com/justfortaste/p/3198406.html

猜你喜欢

转载自blog.csdn.net/spb3732/article/details/85089168
今日推荐