1. 堆的申请
1.1 过程介绍
关于堆的描述,已经简单的在上面一篇文章中做过简单的介绍。具体可以参考 chunk 和 bins
下面我们来回溯下堆的申请过程
申请的顺序:
- 如果申请40B大小的chunk,首先去 fast bins 查看链表中是否有合适的,如果有直接返回地址。如果没有,进行下一步
- small chunk 里面查找是否有匹配的chunk,如果查找到,直接返回指针地址。 如果没有,进行下一步
- 在 unsorted bins 查找,如果没有找到,把 fast bins 里面的bins 放入 unsorted bins,进行合并,看看是否有满足的,进行切割或者重组,重新分配到 small bins 或者 large bins
- 如果申请的 > 512B,则去large bins 里面去查找。 如果找到进入下一步,大小类似的可以进行切换,比如有个 568b 的,切割 512b 返回指针供用户态使用,剩下的56b,重新放入到unsorted bins。等待下次申请的时候,再次重新分配。
- top chunk。 top chunk 通过移动brk,向内核空间申请
- 对于大于 128k,使用mmap 申请内存。(申请之后的free 会直接释放,返还给内核空间)
1.2 例子演示
示例:申请大小不同的内存块
下图是:通过堆申请内存空间的时候,在heap中的形象表示。
输出结果,打印地址
前面三个是连续的(紧挨着的),后面一个相差比较大,是从 mmap 分配的
如果申请8K的不够用了,P6是从 P3后面重新申请的
2. 堆的释放
示例代码:
可以看出 P5的地址和P1是一样的
根据结果倒推理论:
释放的 unsorted bins 对 32k 的进行切割,分给 24 k ,剩下的8k 放到自己上
再次申请6k的chunk
P6 申请了6k,unsorted bins 的 8k 进行再分配
申请8k
如果申请了8k,就不行了 ,因为bins 的 chunk 有头部大小,所以不能简单的 24 + 8
需要从尾部重新分配地址空间
3. 堆的合并
地址是连续的
过程推演
- 释放 32k ,会放到 unsorted bins
- 申请 12k,先从 fast bins 中查找,没有找到,然后去 small bins 没有。 然后去 unsorted bins ,有一个 32k的
进行切割,12k 返回,剩下的20k 放到 unsorted bins - 申请 80k k,先从 fast bins 中查找,没有找到,然后去 small bins 没有。 然后去 unsorted bins
没有,然后就去把 small bins 的拿过来放到 unsorted bins ,合并 。 可进行84k 的切割,80k 的返回
剩下的 4k 放到 unsorted bins
100. 致敬
如有不详,请参考王老师的精彩讲解 堆栈管理
学习过程中,获得了极大的满足感,把之前的一些东西串联了起来。十分感谢 王利涛老师。
在此表示感谢。
PS:本文中所有的资源和图片均来自视频中
另外十分推荐一本书 深入理解计算机系统
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。