• 【内存管理】STL空间配置器


    下面主要介绍STL中实现的内存空间配置器.

    关键点:

    1).考虑到小型区块所可能造成的内存破碎问题,设计了双层级配置器.

    当配置区块超过128bytes时,调用第一层级配置器,第一层级配置器直接使用malloc()和free().

    当配置区块小于128bytes时,调用第二层级配置器,采用复杂的memory pool整理方式,降低额外开销.

    2).内存池管理方式是每次配置一大块内存,并维护对应之自由链表.

    若有相同大小的内存分配,就直接从自由链表中分配内存块.

    若内存释放时,则由配置器回收到自由链表中.

    第二级配置器会主动将任何小额区块的内存需求量调至8的倍数.

    3).自由链表(free-list)节点的结构如下:

    利用union的特性,从第一字段观之,obj可被视为一个指针,指向相同形式的另一个obj.

    从第二字段观之,obj可被视为一个指针,指向实际区块.

    一物二用,不会为了维护链表所必须的指针而造成内存的一种浪费.

    具体代码实现,请参考STL源码.下面附几张图说明.

    第一级配置器与第二级配置器之间的关系:

    第二级配置器分配内存时,自由链表变化示意图:

    第二级配置器释放内存时,自由链表变化示意图:

    第二级配置器分配内存时,其具体步骤如下:

    1).判断内存块大小,是否大于128bytes,若大于,则调用第一级配置器.若小于,进行步骤2).

    2).从16个自由链表中,根据内存块大小选择合适的自由链表.

    3).判断自由链表是否为空,若为空,则重新真充自由链表,否则,进行步骤4).

    4).调整当前自由链表指向一块内存块,并返回当前的内存块.(类似于链表的删除操作)

    第二级配置器释放内存时,其具体步骤如下:

    1).判断内存块大小,是否大于128bytes,若大于,则调用第一级配置器.若小于,进行步骤2).

    2).从16个自由链表中,根据内存块大小选择合适的自由链表.

    3).调整当前自由链表回收当前的内存块.(类似于链表的插入操作)

    内存池的实际操作结果示意图:

    内存池管理:

    1).三个变量来标识内存池的使用情况和大小,start_free,end_free,heap_size.

    2).从内存池中取空间给自由链表时,主要分三种情况进行.

    a).内存池剩余空间完全满足需求量,则直接修改start_free的值,返回对应的区块.

    b).内存池剩余空间不能完全满足需求量,但足够供应一个(含)以上的区块,则减少分配的区块数目,然后分配.

    c).内存池剩余空间连一个区块的大小都无法提供,则利用malloc增加内存空间.

    若malloc成功,则修改start_free,end_free,heap_size,然后递归调用自身,重新分配区块.

    若malloc不成功,则寻找自由链表中,看是否存在足够大的区块.

    若存在,则将对应区块作为内存池,调整start_free,end_free,递归调用自身,重新分配区块.

    若不存,则调用第一级配置器.

  • 相关阅读:
    恶意代码 第三章作业3
    openGauss使用指南
    Latex从入门到入门(不再更新,原因是博客园不支持latex语法,写的太累了)
    《网络对抗技术》Exp4 恶意代码分析
    恶意代码 第三章作业2
    《网络对抗技术》Exp5 信息搜集与漏洞扫描
    第三章作业数据查询
    实验一密码引擎商用密码算法实现1中遇到的问题
    buuctf学习笔记
    网页设计中的默认字体样式详解
  • 原文地址:https://www.cnblogs.com/dwdxdy/p/2537208.html
Copyright © 2020-2023  润新知