前面的例子咱们已经知道栈是什么。如今咱们来介绍下堆,以及堆的实现过程。html
在此以前,咱们先来回顾下进程的模型数组
图中的:heap 部分,就是咱们所说的堆,咱们能够经过移动 brk
指针 来动态扩充。
或者使用 mmap 申请大的内存块。缓存
咱们能够经过查看进程消息,查看进程的地址状态学习
cd /proc/self
cat maps
知道了堆在进程中的位置,咱们来看下堆的保存形式。spa
堆在进程中主要存在二个地方,一个是heap ,一个是mmap mamp 主要用于存放动态连接库。3d
申请方式:
堆能够经过 malloc 或者 mmap 向系统内核空间申请堆空间。指针
固然这些能够经过配置项修改
注 :mchunk_prev_size : 上一个chunk 的大小。 便于管理,为了后续的chunk 合并code
特别注意 : 申请返回的指针,指向的 user data。
因此若是申请的是 24k,那么堆实际的空间大小 > 24k,由于它包含了头信息视频
通常会是 free 掉的,或者截取剩下的chunkhtm
咱们能够从头部中看出,这个chunk 是否来自主进程,以及它的分配方式。
fd bk 存放链表的指针,双向指针。 一个图形能够很好的解释这个状况。
说完了chunk ,咱们紧接着谈下关联的 bins。
用户经过系统调用,申请使用内存。 使用完以后(好比free以后,程序结束以后),不会当即的返回给内核空间。(不断的切换用户态和内核态,系统消耗仍是蛮大的)
因此对于heap中申请的 内存,使用完以后,不会当即释放,而是经过链表的形式保存在用户态,便于下次的再次调用。
bins 按照内存的大小,一共有128个,经过数组的形式来维护起来。
咱们能够从上图中,看出,bins 有
small bins : 小于 512B 的chunk
large bins : 512B - 128K的 chunk
unsorted bins : 通常free 的chunk 大部分会存放到unsorted bins 里面,等待下次申请时候,再分配。 另外切割剩下的部分也会被放到 unsorted bins。 因此更多的像是一个temp ,中转站
fast bins : 至关于 bins 的缓存,采用单链表的形式,便于快速查询使用。通常都是比较小的chunk,大小是0-64B。
若有不详,请参考王老师的精彩讲解 堆栈管理
学习过程当中,得到了极大的知足感,把以前的一些东西串联了起来。十分感谢 王利涛老师。
在此表示感谢。
PS:本文中全部的资源和图片均来自视频中
另外十分推荐一本书 深刻理解计算机系统