【学习笔记】3. 内存的 chunk 和 bins

1. 什么是堆

前面的例子咱们已经知道栈是什么。如今咱们来介绍下堆,以及堆的实现过程。html

在此以前,咱们先来回顾下进程的模型数组

clipboard.png

图中的:heap 部分,就是咱们所说的堆,咱们能够经过移动 brk 指针 来动态扩充。
或者使用 mmap 申请大的内存块。缓存

1.1 堆在进程中的地址分布

咱们能够经过查看进程消息,查看进程的地址状态学习

cd /proc/self
cat maps

clipboard.png

clipboard.png

知道了堆在进程中的位置,咱们来看下堆的保存形式。spa

1.2 堆的申请方式

堆在进程中主要存在二个地方,一个是heap ,一个是mmap mamp 主要用于存放动态连接库。3d

申请方式:
堆能够经过 malloc 或者 mmap 向系统内核空间申请堆空间。指针

  • 对于通常大小的堆的申请,使用malloc
  • 对于大于128K的申请,使用 mmap。
固然这些能够经过配置项修改

1.3 堆的结构体

clipboard.png

注 :mchunk_prev_size : 上一个chunk 的大小。 便于管理,为了后续的chunk 合并code

1.3.1 已分配出去的chunk

clipboard.png

特别注意 : 申请返回的指针,指向的 user data。
因此若是申请的是 24k,那么堆实际的空间大小 > 24k,由于它包含了头信息视频

1.3.2 空闲的chunk

通常会是 free 掉的,或者截取剩下的chunkhtm

clipboard.png

咱们能够从头部中看出,这个chunk 是否来自主进程,以及它的分配方式。

fd bk 存放链表的指针,双向指针。 一个图形能够很好的解释这个状况。

clipboard.png

2. bins

2.1 为何使用 bins

说完了chunk ,咱们紧接着谈下关联的 bins。

用户经过系统调用,申请使用内存。 使用完以后(好比free以后,程序结束以后),不会当即的返回给内核空间。(不断的切换用户态和内核态,系统消耗仍是蛮大的)

因此对于heap中申请的 内存,使用完以后,不会当即释放,而是经过链表的形式保存在用户态,便于下次的再次调用。

clipboard.png

bins 按照内存的大小,一共有128个,经过数组的形式来维护起来。

clipboard.png

2.2 bins 的分类

咱们能够从上图中,看出,bins 有

  1. Fast bins
  2. unsorted bins
  3. Small bins
  4. Large 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。

2.3 bins 的调用顺序

  1. fast bins。 针对小字节的chunk ,第一步先从 fast chunk 里面查找。 由于是单链表,且是相同大小的,速度比较快。
  2. small bins : 单个链表下chunk大小相同,不一样链表的chunk间隔是8B。
  3. unsorted bins: 先查询 unsorted bins 有没有合适的,若是没有,会把 fast bins 中的bins 拿过来,用于合并和切割。 而后分配到 small bins 和 large bins。
  4. large bins,一个链表中大小不同,是处于一个范围内,间隔也不相同。
  5. top chunk。 对于从large bins 查找不到的内存块,须要从heap 旁的chunk 去申请。能够经过移动brk 指针
  6. mmap chunk。 对于大于 128k,须要从mmap 中申请

100. 致敬

若有不详,请参考王老师的精彩讲解 堆栈管理
学习过程当中,得到了极大的知足感,把以前的一些东西串联了起来。十分感谢 王利涛老师
在此表示感谢。
PS:本文中全部的资源和图片均来自视频中
另外十分推荐一本书 深刻理解计算机系统

相关文章
相关标签/搜索