ptmalloc一些细节流程

  • chunk 容器
  1. Bins
  • ptmalloc统一管理heap和mmap区的chunk,避免了频繁的系统调用,一共维护了128个bin,使用数组来存储,所有的bin都是双向链表。

 

  2.Fast Bins

    • 对于不大于max_fast的chunk加入fast bins,标志位P不改变(为了不使其合并),在认为内存碎片太多时会将其合并加入unsorted bin。

  3.Unsorted Bin

    • 对于回收的chunk大于max_fast或合并完的 fast bin 会加在这里,在fast bin中没有找到合适的chunk后,会在这里找,如果没有将其加入到合适的bin中,相当于其他bin的高速缓存。

  4.Top chunk

    • 在sub_heap的最高处不属于任何chunk,总是在small bin 和large bin 后考虑,与收缩条件息息相关。

  5.mmap chunk

    • 申请的内存足够大时,直接使用mmap向系统申请资源,同时释放时也是直接解除映射。

  6.Last remainder

    • 一种特殊的chunk,不属于任何bin,当需要分配一个small chunk时,没有相应的chunk,last remainder chunk会分裂成两个,一个返回给用户,另一个变成新的last remainder chunk。
  • 核心结构
  1. 对于主分配区,使用了静态全局的结构体定义(malloc_par),保证只有一份。
  2. 对于非主分配区,由多个sub_heap组成。第一个sub_heap中,最顶端是heap_info,接下来是malloc_state的实例(保存了分配去相应的信息),接下来是chunk。heap_info中利用单链表将sub_heap连接起来,后续的sub_heap由heap_info和chunk构成。
  • 初始化
  1. 分配区的初始化:首先遍历所有的bins,修改指针指向,设置了全局变量global_max_fast,在主分配区初始化时赋值,最后初始化top_chunk。
  2. ptmalloc初始化:
  • 调用malloc前定义了hooks函数,对ptmalloc进行初始化,对于多线程的ptmalloc,同时需要调用pthread_initilaize初始化pthread。
  • 定义了判断是否初始化过的全局变量_malloc_initalized(值为1时说明初始化完成)。
  • 初始化全局锁list_lock用于同步分配区的单向循环链表,创建线程私有实例arena_key只想主分配区,以后每次分配内存后调整arena_key使不总在一个分配区分配资源。
  • 初始化fork子进程时调用的回调函数:在本线程fork子进程时,调用ptmalloc_lock_all()获得所有分配区的锁,当子进程创建完毕时,父进程调用ptmalloc_unlock_all()重新unlock每个分配区的锁,子进程调用ptmallic_unlock_all2()重新初始化每个分配区的锁。对于从父进程继承的锁不安全会造成内存泄漏,所以需要重新初始化。另外对于递归fork子进程时,使用了atfork_recursive_cntr引用计数,方便父进程正确解锁。
  • 获取分配区:(PER_THREAD开启)首先尝试从分配区的free_list中获得一个分配区(由父进程继承而来),如果没有则尝试重用分配区,如果仍然没有则创建新的分配区。    
  • 当_int_malloc()函数尝试从fast bins,last remainder chunk,small bins,large bins和top chunk都失败都就会使用sysMalloc()函数直接向系统申请内存用于分配所需的chunk。

                                                                                                                                                                                                                                                                                                                                                                                                             

转载于:https://www.cnblogs.com/zhangtiezi/p/8459792.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 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、付费专栏及课程。

余额充值