glibc的malloc实现,会按照分配内存大小的不同而使用不用的方法,小空间的分配会直接使用堆,大空间的分配使用的就是匿名内存映射。(目前是以128KB的空间为大小的界限)

堆实现

简单的说,就是把数据段切分为一系列2的整数幂大小的块,然后相邻的分区,哪里有位置,就使用哪里的内存;不用了就标记一个"不使用"。一般堆的顶端都有一个端点,如果当前堆顶是空的,可以调用 brk(),降低断点的位置,将空间返还给系统。

我理解的内部碎片和外部碎片
我理解的内部碎片和外部碎片

堆实现的这个"伙伴内存分配算法",虽然高速简单,但是会产生"内部碎片"和"外部碎片"。内部碎片降低空间的利用率。外部碎片则是有内存空间却由于被分成不同块而无法使用。

内存映射实现

匿名内存映射和基于文件的映射很像,匿名内存映射使用 mmap() 时,start 参数使用NULL,也就是说不管映射在什么地方,所以叫匿名。

使用匿名内存映射后,妈妈再也不用担心我的内存碎片问题了,不用直接取消映射就好,想用再映射回来。但是凡事有优点就有缺点,每个内存映射都是页的大小的整数倍,也就是说,需要分配的空间越小,对空间的浪费就越多;所以只有在对大量空间分配时才使用内存映射。

参考源