ptmalloc的实现细节

如果对ptmalloc的基本设计还不熟悉,请先看:https://blog.csdn.net/songchuwang1868/article/details/89951543

一、bin数组

bin数组大体分成三个部分:

1、unsored bin数组

  • 暂存一些没有排序的数据
  • unsored bin数组中的块马上就会分配给用户或者放到small/large bin数组中

2、small bin数组

  • 每项指向一个双向链表,链表中每一项都是一样的大小
  • 最小32Byte,16Byte递增,直到1K

3、large bin数组

  • 每项是一个范围
  • 每项指向的是双向链表,双向链表维护有序的块,除了fd和bk外还有fd_nextsize和bk_nextsize的使用

二、fast bin数组

  • 独立于前面的bin数组
  • 最小32Byte,16Byte递增,直到128Byte
  • 单向链表,便于使用CAS实现无锁操作
  • 使用arena分配内存时,先到fast bin中找,找到匹配的块直接返回,找到更大的块,切割需要的大小返回。由于fast bin中的块很散碎而没有找到,摘取fast bin中所有的块,进行合并。将合并后更大的块放到unsored bin中,遍历unsored bin找需要的块,遍历过程中顺便将unsored bin中的块放到small bin和large bin中。

三、arena

  • 每个arena中包含了一个bin和一个fast_bin
  • 每个进程中有最多有N个arena,N=cpu_num*2(32位系统),也就是说arena数仅仅与cpu数目相关
  • ptmalloc是C库中的功能,所以必定在用户层上,所以必定每个进程一份,也就是说每个进程有N个arena。所有跨越进程的共享资源都在内核中维护
  • 同一个进程中的多个线程共享这对应进程中的N个arena
  • 多个线程可以绑定到同一个arena上,当部分arena耗尽的情况下,一个线程也可能切换到其他arena

四、top chunk

  • 每当arena管理的内存不够时,使用mmap(非主arena)或者brk(主arena)分配1M大小的堆空间
  • 虽然分配了1M的空间,但不是直接使用,而是每次用4K,也就是每次用一个页面。未用到的页面设定为protected页,如果用户误写了protected页,段错误
  • 在一个可用页中切割chunk
  • top chunk指向已切割chunk的最后,换言之,每次切割新的chunk,从top chunk处开始
  • 当归还内存时,归还的chunk会与top chunk合并(也就是top chunk上移)

五、heap

  • 这里的heap不是内存布局中的heap,而是一个malloc中的结构体
  • arena可能使用的内存超过1M,会分配多个Heap,并用链表维护
  • top chunk位域最后一个heap的最后一个chunk的后面
  • arena位于第一个Heap中
  • Heap1 M对齐,任意一个chunk要找到自己属于哪一个arena是很容易的,只看自己的高位,便能找到自己所属的heap,再定位到相应的arena
  • 归还内存,使top chunk位移到heap开始的地方,说明整个heap都归还了,ptmalloc将整个heap还给系统
  • ptmalloc这里存在一个槽点,如果中间的heap基本空闲(但有几个chunk还没有回收),但对应的heap却得不到回收

六、thread cache

最新版的ptmalloc向tc malloc学习,使用了线程局部存储来优化设计,线性局部存储不熟请看:https://blog.csdn.net/songchuwang1868/article/details/90143332

ptmalloc中的thread cache有如下特点:

  • tcache与small bin类似,最小32Byte,16Byte递增,直到1K
  • 每个链表最多7个chunk
  • 每次申请内存,先到thread cache中找,没有再到arena中取找

七、分配流程

  1. 有thread cache,先到thread cache中找
  2. 到fast bin中找
  3. 到small bin中找,找到返回,没有找到开始清理fast bin
  4. 将fast bin中的块取下来,相邻的合并,放到unsorted bin中
  5. 遍历unsorted bin,如果能够分配,进行分配,不能分配将其挂到bin中相应的位置
  6. 到large bin中找,如果能够分配,进行切割,一部分交给用户,剩余部分放到unsorted bin中
  7. 如果遍历完lare bin没有找到,mmap新内存

八、回收流程

  1. 有thread cache,且大小合适,放到thread cache中
  2. 放到fast bin中,无论当前fast bin中有多少块,只要在fast bin的chunk size范围内,就放到fast bin中
  3. 放到bin(包括small bin和large bin)中,放的时候看能不能与相邻块合并,合并后放到unsorted bin中
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
本文通过Glibc的内存暴增问题,主要介绍了系统的内存管理问题,具体如下: 目录 1. 问题 2. 基础知识 2.1 X86平台Linux进程内存布局 2.1.1 32位模式下进程内存经典布局 2.1.2 32位模式下进程默认内存布局 2.1.3 64位模式下进程内存布局 2.2 操作系统内存分配的相关函数 2.2.1 Heap操作相关函数 2.2.2 Mmap映射区域操作相关函数 3. 概述 3.1 内存管理一般性描述 3.1.1 内存管理的方法 3.1.2 内存管理器的设计目标 3.1.3 常见C内存管理程序 3.2 Ptmalloc内存管理概述 3.2.1 简介 3.2.2 内存管理的设计假设 3.2.3 内存管理数据结构概述 3.2.4 内存分配概述 3.2.5 内存回收概述 3.2.6 配置选项概述 3.2.7 使用注意事项 4. 问题分析及解决 5. 源代码分析 5.1 边界标记法 5.2 分箱式内存管理 5.2.1 Small bins 5.2.2 Large bins 5.2.3 Unsorted bin 5.2.4 Fast bins 5.3 核心结构体分析 5.3.1 malloc_state 5.3.2 Malloc_par 5.3.3 分配区的初始化 5.4 配置选项 5.5 Ptmalloc的初始化 5.5.1 Ptmalloc未初始化时分配/释放内存 5.5.2 ptmalloc_init()函数 5.5.3 ptmalloc_lock_all(),ptmalloc_unlock_all(),ptmalloc_unlock_all2() 5.6 多分配区支持 5.6.1 Heap_info 5.6.2 获取分配区 5.6.3 Arena_get2() 5.6.4 _int_new_arena() 5.6.5 New_heap() 5.6.6 get_free_list()和reused_arena() 5.6.7 grow_heap(),shrink_heap(),delete_heap(),heap_trim() 5.7 内存分配malloc 5.7.1 public_mALLOc() 5.7.2 _int_malloc() 5.8 内存释放free 5.8.1 Public_fREe() 5.8.2 _int_free() 5.8.3 sYSTRIm()和munmap_chunk(

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值