1.当堆中的空间不足时,malloc会调用sbrk系统调用来想操作系统申请获得更多的堆空间。虽然sbrk可以扩充货缩小进程的存储空间,但是大多数malloc和free的实现都不减小进程的存储空间。释放的空间可供以后再分配,但通常将他们保持在malloc池中而不返回给内核。
2.堆中的空闲块组成一个空闲链表,每个空闲块在开始处都有一个结构用于存放管理记录,在管理记录中存放着该块的大小(size)和指向下一个块的指针,管理记录后是空闲空间。这些空闲块按地址增序组织成链表,且最后一个块指向第一个块。
3.malloc申请过程:当调用malloc申请空间时,遍历空闲块链表直到找到一个能满足申请空间大小的空闲块(first fit)。如果空闲块的大小刚好等于申请空间的大小时,则将此空闲块从空闲块链表中断开并将此空闲空间返回给用户;如果空闲块的大小比申请的空间大的话,则要将空间块划分,前面满足申请大小的空间返回给用户,后面余下的空闲空间继续放在空闲链表中。如果没有找到满足申请空间的空闲空间,则向操作系统申请另一足够大的空闲空间并链接到空闲空间链表中。
4.free操作同样要搜索空闲空间链表,以便找到合适的地方插入被释放的块。如果释放的内存空间在两边都有空闲块相连则将其合并成一个大的空闲块。
5.解决内存对齐问题
typedef long Align;
union header {
struct {
union header *ptr;
unsigned size;
} s;
Align x;
};
typedef union header Header;
在解释内存对齐的作用前,先来看下内存对齐的规则:
- 对于结构的各个成员,第一个成员位于偏移为0的位置,以后每个数据成员的偏移量必须是min(#pragma pack()指定的数,这个数据成员的自身长度) 的倍数。
- 在数据成员完成各自对齐之后,结构(或联合)本身也要进行对齐,对齐将按照#pragma pack指定的数值和结构(或联合)最大数据成员长度中,比较小的那个进行。
内存对齐的主要作用是:
- 平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
- 性能原因:经过内存对齐后,CPU的内存访问速度大大提升。具体原因稍后解释。
6.如果在超过一个已分配区的尾端进行写操作,则会中写后一个块的管理记录,同样在已分配区起始位置之前进行写操作会重写本块的管理记录。