二 内存分配

内存基本处理工具:


STL定义了五个全局函数,作用于未初始化空间上。这在容器的实现上很有帮助。

Construct():用于构造

Destroy():用于析构

Uninitialized_copy():POD:直接用STL算法copy();non_POD:单个元素构造construct().对char*类型元素,直接内存底层操作快速移动:memmove()效率极高

Uninitialized_fill():POD:直接用STL算法fill();non_POD:单个元素构造construct()

Uninitialied_fill_n():POD:直接用STL算法fill_n();non_POD:单个元素构造construct()

Copy():强化效率无所不用其极: has trivialoperator=:    memmove()速度极快

                              Has non_trivial operator=:  循环处理

For(;first!=last;++first)与for(n=0;n<last-first;++n):以比较n来执行循环,比迭代器的比较执行循环速度快。(迭代器可能自定义类或内置指针等,其比较。。。)

 

SGI 内存池:

 内存池的分类:
     
一、不定长内存池:优点:不需要为不同的数据创建不同的内存池,缺点是分配出去的内存池不能回收到池中(?)。代表有apr_poolobstack
     
二、定长内存池:优点:使用完立即把内存归还池中。代表有Loki, Boost
     
本次以sgi stl中实现的内存池作为学习对象。由于要实现的是一个C语言的内存池,所以这里用C的描述方式。喜欢C++的朋友可以直接看源文件或者《STL源码剖析》的讲解。sgi设计了二级配置机制,第一级配置器直接使用malloc()free()。当配置区块超过128 bytes时,则采用第一级配置器;否则采用memory pool方式。
      memory pool
的整体思想是维护128/8 = 16个自由链表,这里的8是小型区块的上调边界。每个自由链表串接的区块大小如下:

序号

0

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

串接区块

8

16

24

32

40

48

56

64

72

80

88

96

104

112

120

128

范围

1-8

9-16

17-24

25-32

33-40

41-48

49-56

57-64

65-72

73-80

81-88

89-96

97-104

105-112

113-120

121-128

 

 

 

   



 几个过程的思路:
    

  一、申请过程:

Code:

1.  if (用户申请的内存不大于128 bytes)  

2.      查找对应的链表   

3.      if (对应链表拥有一块以上的区块)   

4.          调整链表   

5.          返回第一个区块地址   

6.      else  

7.          准备重新填充链表   

8.              向内存池申请内存(指定数量的区块)   

9.              if (内存池申请到一个区块)   

10.                返回第一个区块地址   

11.             else  

12.                调整链表,将区块串接起来   

13.                返回第一个区块地址   

14. else  

15.     直接用malloc()申请内存  

   

     二、释放过程:

Code:

1.  if (用户释放的内存块大于128 bytes)  

2.      直接用free()释放   

3.  else  

4.      查找对应的链表   

5.     回收内存  

    

   三、向内存池申请内存过程:

Code:

1.  if (内存池空间完全满足需求量)   

2.      调整内存池起始位置   

3.      返回空间地址   

4.  else if (内存池空间不能完全满足需求量,但能提供一个以上的区块)  

5.      计算能够提供的最大内存   

6.      调整内存池起始位置   

7.      返回空间地址   

8.  else  

9.      从内存池中压缩内存   

10.     收集比size大的空间   

11.     递归调用,修正nobjs   

12.     再次申请内存,可能抛出异常  


      chunk_alloc的作用是从内存池中取内存给free list,所以会竭尽全力满足用户需要。如果有足够的空间,会返回指定数量的区块,否者返回实际能提供数量的区块,或者无法满足用户需要,那么会将内存池剩下的零头编入适当的链表中,然后向系统索要空间来补充内存池。如果系统也无内存可用,则寻找free list中是否有比size大的区块,将其用来补充空间。如果到处都已无内存可用了,会再次配置空间,可能抛出异常。否则记录内存池大小。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值