堆学习基础

1、什么是堆?

  • 是虚拟地址空间的一块连续的线性区域
  • 提供动态分配的内存,允许程序申请大小未知的内存
  • 在用户与操作系统之间,作为动态内存管理的中间人
  • 响应用户的申请内存请求,向操作系统申请内存,然后将其返回给用户程序
  • 管理用户所释放的内存,适时归还给操作系统

2、各种堆管理器

  • dlmalloc- General purpose allocator
    - ptmalloc2 - glibc(Linux系统使用的libc) 本文重点学习
  • jemalloc - FreeBSD and Firefox
  • tcmalloc - Google
  • libumem - Solaris

堆管理器并非由操作系统实现,而是由libc.so.6链接库实现。封装了一些系统调用,为用户提供方便的动态内存分配接口的同时,力求高效地管理由系统调用申请来的内存。

  • 申请内存的系统调用:(子线程只能用mmap,主线程都可以)
    • brk(从data向上扩展一段空间作为堆空间)
    • mmap(直接调用一段空间作为堆空间)
      在这里插入图片描述

3、堆管理器是如何工作的?

三个关键字:

  • arena
  • chunk
  • bin
3.1 arena

内存分配区,可以理解为堆管理器所持有的内存池
在这里插入图片描述

堆管理器与用户的内存交易发生于arena中
可以理解为堆管理器向操作系统批发来的有冗余的内存库存

3.2 chunk

用户申请内存的单位,也是堆管理器管理内存的基本单位
malloc()返回的指针指向一个chunk的数据区域
在这里插入图片描述

chunk在glibc中的实现:
在这里插入图片描述

malloced chunk结构:
在这里插入图片描述

注意:prev size指得是上一个free_chunk 的大小
free chunk结构:
在这里插入图片描述

注意:p =0 指得是上一个chunk为free_chunk,p=1就是上一个chunk写有数据。发现p=0和上面free_chunk进行合并,改动上一个free_chunk的size即可;
在这里插入图片描述


3.3 bin

管理arena中空闲chunk的结构
以数组的形式存在,数组元素为相应大小的chunk链表的链表头
存在于arena的malloc_state中

  • unsorted bin
  • fast bins
  • small bins
  • large bins
  • (tcache)
    unsorted bin结构:
    保留一些大小不一的杂的free_chunk,注意fd指向下一个chunk,bk指向上一个。
  • bins[1]
  • 管理刚刚释放还为分类的chunk
  • 可以视为空闲chunk回归其所属bin之前的缓冲区
    在这里插入图片描述

small bins: 多个unsorted bin头两个串起来

  • bins[2] ~ bin[63]
  • 62个循环双向链表
  • FIFO 先进先出
  • 管理16、24、32…、504Bytes的free chunks(32位下)
  • 每个链表中存储的chunk大小都一致
    在这里插入图片描述

fast bins结构:

  • fastbinsY[]
  • 单向列表
  • LIFO – 后入先出
  • 管理16、24、32、40、48、56、64Bytes的free chunks(32位下默认,64位*2就行)
  • 其中的chunk的in_use 位(下一个物理相邻的chunk的P位)总位1,为了不被free chunk合并,更快分配chunk
    在这里插入图片描述

large bins结构:

  • bins[64] ~ bins[126]
  • 63个循环双向链表
  • FIFO
  • 管理大于504Bytes的free chunks(32位下)
    在这里插入图片描述

malloc_state
在这里插入图片描述

3.4 tcache

与fastbin很像,管理还没分配过的一大段free_chunk

4、堆漏洞

有系统的地方就有漏洞:

  • UAF
  • Buffer Overflow
  • Double Free
  • Off-by-One
  • Unlink
    . . . . . .

5、相关学习资料:

国外师傅总结heap
适合新手入门的GitHub项目学习

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值