SGI 内存池

内存池:是解决内存碎片的主要方法,由于new和malloc是直接从操作系统那里通过其算法申请内存,每次申请操作系统都要执行一次,所以申请效率不仅不高,而且频繁的申请与释放内存会形成大量的内存碎片。而内存池的主要思想就是在初始化时就分配一大块内存给程序,当需要内存时,就从这一大块中切给程序,当释放时,也是释放到内存池中,并没有释放给操作系统。这样会大大的减少内存碎片,因为所有的内存操作都只在这个内存池中进行。注意:只有频繁申请和释放内存时使用内存池才是较好的解决办法,如果只是少量的就不必使用内存池。
SGI中的Alloc类是我见过设计最优秀的内存池之一,其原理主要如下:
对于所有容器,STL默认都使用alloc类来对容器进行内存分配,而alloc内中有第一级和第二级内存配置方式。其中,第一级内存配置是对于内存需求大于128byte的对象,当小于128byte时,就采用第二级配置器,即内存池的方式进行分配内存。第一级的分配方式是直接以malloc函数进行分配。
内存池:SGI中内存池类似堆。首先,用一个16个成员的数组free_list来维护小内存,每个成员分别装的是内存大小为8byte-16-32-…-128byte的链表头,每个成员都维护着一个链表。对于要分配的内存字节,首先将之上调至8的倍数,然后对free_list中的成员进行匹配(有专门的函数完成),匹配成功以后,就将该成员下的节点分配给该所需的内存,然后将该节点删除,使链表头所指的内存始终处于空闲状态。当释放内存时,也是首先进行成员匹配,匹配成功以后,利用链表的头插法将内存插入到链表头前面,成为新的链表头。
默认每个成员分配20个节点,当所有节点用完以后,再次申请内存时,就调用refill()函数为free_list重新填充空间,新空间从内存池中获得,默认取20个节点的空间,得到空间以后按该数组成员所管理的字节数重新分配形成新的链表,从内存池(chunk_alloc函数完成)中取出内存分配给该成员,由于链表中的节点都已经用完,所以新分配的内存的头节点就成为链表头。若内存池中内存不够,则有多少就分配多少个节点给该成员。如果一个也分配不出来,chunk_alloc就调用malloc向自由空间(堆)申请内存到内存池中,申请的内存大小为所需内存的2倍,例如:如果申请32byte的内存20个,则malloc申请的内存为32byte*40。
在使用过程中,由于容器默认的就是alloc类进行内存分配,所以在初始化时,由于free_list中都是空的,在申请内存时,chunk_alloc就会向堆空间中申请内存,注意,所需内存是多大,那么就只分配给free_list中相应的成员内存空间形成链表结构,而其他成员仍然是空的。只有需要时才分配。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值