0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

百度工程师带你探秘C++内存管理

C语言与CPP编程 来源:C语言与CPP编程 作者:daydreamer 2022-12-20 09:32 次阅读

前篇《探秘C++内存管理(理论篇)》主要介绍了Linux C++程序内存管理的理论基础,本文作为系列文章《探秘C++内存管理》的第二篇,将会探讨经典内存管理器ptmalloc如何管理C++程序的内存。借助剖析ptmalloc解决问题的着重点和设计实现成本的权衡,更具体的呈现c++内存管理面临的问题和工程落地中的巧思。

一、概述

GEEK TALK

ptmalloc是开源GNU C Library(glibc)默认的内存管理器,当前大部分Linux服务端程序使用的是ptmalloc提供的malloc/free系列函数,而它在性能上远差于Meta的jemalloc和Google的tcmalloc。服务端程序调用ptmalloc提供的malloc/free函数申请和释放内存,ptmalloc提供对内存的集中管理,以尽可能达到:

用户申请和释放内存更加高效,避免多线程申请内存并发和加锁

寻求与操作系统交互过程中内存占用和malloc/free性能消耗的平衡点,降低内存碎片化,不频繁调用系统调用函数

简单概括ptmalloc的内存管理策略:

预先向操作系统申请并持有一块内存供用户malloc,同时管理已使用和空闲的内存

用户执行free,会将回收的内存管理起来,并执行管理策略决定是否交还给操作系统

接下来,将从ptmalloc数据结构、内存分配及优缺点介绍最经典的c++内存管理器的实现和使用(以32位机为例)。

二、内存管理

GEEK TALK

2.1 数据结构

为了解决多线程锁争夺问题,将内存分配区分为主分配区(main_area)和非主分配区(no_main_area)。同时,为了便于管理内存,对预申请的内存采用边界标记法划分成很多块(chunk);ptmalloc内存分配器中,malloc_chunk是基本组织单元,用于管理不同类型的chunk,功能和大小相近的chunk串联成链表,被称为一个bin。

main_arena与non_main_arena

主分配区和非主分配区形成一个环形链表进行管理, 每一个分配区利用互斥锁实现线程对该分配区的访问互斥。每个进程只有一个主分配区,但允许有多个非主分配区,且非主分配区的数量只增加不减少。主分配区可以访问进程的heap区域和mmap映射区域,即主分配区可以使用sbrk()和mmap()分配内存;非主分配区只能使用mmap()分配内存。

810763b4-7fff-11ed-8abf-dac502259ad0.png

对于不同arena的管理策略大致如下:

分配内存

查看该线程的私有变量中是否已经存在一个分配区并对其进行加锁操作,如果加锁成功,则使用该分配区分配内存;如果未找到该分区或加锁失败,遍历环形链表中获取一个未加锁的分配区

如果整个环形链表中没有未加锁的分配区,开辟一个新的分配区,将其加入循环链表并加锁,使用该分配区满足当前线程的内存分配

释放内存

先获取待释放内存块所在的分配区的锁,如果有其他线程正在使用该分配区,等待其他线程释放该分配区互斥锁后,再释放内存

主分配区和非主分配区的结构如下:

81161d78-7fff-11ed-8abf-dac502259ad0.png

其中fastbinsY和bins是对实际内存块的管理和操作结构:

fastbinsY:用以保存fast bins

bins[NBINS * 2 - 2]:unsorted bin(1个,bin[1])、small bins(62 个,bin[2]~bin[63])、large bins(63 个,bin[64]~bin[126])的集合,一共有 126 个表项(NBINS = 128),bin[0] 和 bin[127] 没有被使用

malloc_chunk与bins

ptmalloc统一管理heap和mmap映射区域中空闲的chunk,当用户进行分配请求时,会先试图在空闲的chunk中查找和分割,从而避免频繁的系统调用,降低内存分配的开销。为了更好的管理和查找空闲chunk,在预分配的空间的前后添加了必要的控制信息,内存管理结构malloc_chunk的成员及作用如下:

8135e2b6-7fff-11ed-8abf-dac502259ad0.png

mchunk_prev_size: 前一个空闲chunk的大小

mchunk_size: 当前chunk的大小

必要的属性标志位:

前一个chunk在使用中(P = 1)

当前chunk是mmap映射区域分配(M = 1)或是heap区域分配(M = 0)

当前chunk属于非主分配区(A = 0)或非主分配区(A = 1)

fd和bk: chunk块空闲时存在,用于将空闲chunk块加入到空闲chunk块链表中统一管理

基于chunk的大小和使用方法,划分出以下几种bins:

81475190-7fff-11ed-8abf-dac502259ad0.png

fast bins

fast bins仅保存很小的堆,采用单链表串联,增删chunk都发生在链表的头部,进一步提高小内存的分配效率。fast bins记录着大小以8字节递增的bin链表,一般不会和其他堆块合并。

unsorted bin

small bins和large bins的缓冲区,用于加快分配的速度,chunk大小无尺寸限制,用户释放的堆块,会先进入unsorted bin。分配堆块时,会优先检查unsorted bin链表中是否存在合适的堆块,并进行切割并返回。

small bins

保存大小 < 512B的chunk的bin被称为small bins。small bins每个bin之间相差8个字节,同一个small bin中的chunk具有相同大小,采用双向循环链表串联。

large bins

保存大小 >= 512B的chunk的bin被称为large bins。large bins中的每一个bin分别包含了一个给定范围内的chunk,其中的chunk按大小降序,相同大小按时间降序。

当然,并不是所有chunk都按上述的方式来组织,其他常用的chunk,如:

top chunk: 分配区的顶部空闲内存,当bins不能满足内存分配要求的时候,会尝试在top chunk分配。

当top chunk > 用户请求大小,top chunk会分为两个部分:用户请求大小(user chunk)和剩余top chunk大小(remainder chunk)

当top chunk < 用户所请求大小,top chunk就通过sbrk(main_arena)或mmap(non_main_arena)系统调用来扩容

2.2内存分配与释放

概括内存malloc和free的流程大致如下:

内存分配malloc流程

1、获取分配区的锁

2、计算出需要分配的内存的chunk实际大小

3、如果chunk的大小 < max_fast,在fast bins上查找适合的chunk;如果不存在,转到5

4、如果chunk大小 < 512B,从small bins上去查找chunk,如果存在,分配结束

5、需要分配的是一块大的内存,或者small bins中找不到chunk:

a.遍历fast bins,合并相邻的chunk,并链接到unsorted bin中

b.遍历unsorted bin中的chunk:

-能够切割chunk直接分配,分配结束

-根据chunk的空间大小将其放入small bins或是large bins中,遍历完成后,转到6

6、需要分配的是一块大的内存,或者small bins和unsorted bin中都找不到合适的 chunk,且fast bins和unsorted bin中所有的chunk已清除:

从large bins中查找,反向遍历链表,直到找到第一个大小大于待分配的chunk进行切割,余下放入unsorted bin,分配结束

7、检索fast bins和bins没有找到合适的chunk,判断top chunk大小是否满足所需chunk的大小,从top chunk中分配

8、top chunk不能满足需求,需要扩大top chunk:

a.主分区上,如果分配的内存 < 分配阈值(默认128KB),使用brk()分配;如果分配的内存 > 分配阈值,使用mmap分配

b.非主分区上,使用mmap来分配一块内存

内存释放free流程

1、获取分配区的锁

2、如果free的是空指针,返回

3、如果当前chunk是mmap映射区域映射的内存,调用munmap()释放内存

4、如果chunk与top chunk相邻,直接与top chunk合并,转到8

5、如果chunk的大小 > max_fast,放入unsorted bin,并且检查是否有合并:

a.没有合并情况则free

b.有合并情况并且和top chunk相邻,转到8

6、如果chunk的大小 < max_fast,放入fast bin,并且检查是否有合并:

a.fast bin并没有改变chunk的状态,没有合并情况则free

b.有合并情况,转到7

7、在fast bin,如果相邻chunk空闲,则将这两个chunk合并,放入unsorted bin。如果合并后的大小 > 64KB,会触发进行fast bins的合并操作,fast bins中的chunk将被遍历合并,合并后的chunk会被放到unsorted bin中。合并后的chunk和top chunk相邻,则会合并到top chunk中,转到8

8.如果top chunk的大小 > mmap收缩阈值(默认为128KB),对于主分配区,会试图归还top chunk中的一部分给操作系统

三、优缺点

GEEK TALK

ptmalloc作为glibc默认的内存管理器,已经广泛的满足大多数大型项目的内存管理,同时它的实现思路也对后来的内存管理器提供了借鉴。

8162095e-7fff-11ed-8abf-dac502259ad0.png

ptmalloc的介绍暂告一段落,接下来的几篇文章将继续探讨高性能内存管理库的集大成者——jemalloc、tcmalloc内存管理库。

审核编辑 :李倩

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 操作系统
    +关注

    关注

    37

    文章

    6818

    浏览量

    123318
  • C++
    C++
    +关注

    关注

    22

    文章

    2108

    浏览量

    73636
  • 内存管理
    +关注

    关注

    0

    文章

    168

    浏览量

    14137

原文标题:百度工程师带你探秘C++内存管理(ptmalloc篇)

文章出处:【微信号:C语言与CPP编程,微信公众号:C语言与CPP编程】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    百度正式回应进军短剧领域

    近日,百度在线网络技术(北京)有限公司在知识产权领域有了新的动作,据天眼查信息显示,该公司已申请注册“百度短剧”商标,涵盖网站服务、科学仪器、教育娱乐等多个国际分类,目前这些商标均处于等待实质审查
    的头像 发表于 12-17 14:19 152次阅读

    百度文心大模型日均调用量超15亿

    近日,百度在上海世博中心举办了主题为“应用来了”的百度世界2024大会。会上,百度董事长李彦宏分享了关于大模型行业的最新动态和百度文心大模型的显著进展。
    的头像 发表于 11-12 15:28 284次阅读

    百度将发布AI智能眼镜

    近日,有知情人士透露,百度旗下的人工智能品牌小计划在即将举行的百度世界大会上推出一款全新的AI智能眼镜。这款眼镜将内置先进的人工智能助手,并配备摄像头,为用户提供前所未有的智能体验。
    的头像 发表于 11-11 14:50 418次阅读

    百度市值被低估?分析看好其长期发展潜力

    近期,尽管微软和Meta公布了超预期的财报,但市场对人工智能领域的热情似乎有所减退。在此背景下,中概股也普遍走低,百度同样未能幸免。然而,多位分析百度的长期发展潜力表示看好,认为其市值被低估。
    的头像 发表于 11-05 11:16 561次阅读

    百度舸AI计算平台4.0震撼发布

    在2024年百度云智大会的璀璨舞台上,百度智能云重磅推出了舸AI异构计算平台的全新力作——4.0版本。此次升级,标志着百度在AI基础设施领域迈出了坚实的一步,致力于为行业提供更为强大
    的头像 发表于 09-26 14:46 474次阅读

    百度智能云升级3款大模型应用:面向三类场景打造企业“超级员工”

    6月25日,“AI Cloud Day:百度智能云大模型应用产品发布会”在北京举行。会上,百度智能云面向知识管理、客服、营销,三大企业应用场景,升级百度智能云甄知知识
    的头像 发表于 06-25 19:22 1091次阅读

    百度申请文小言商标

    近日,百度在线网络技术(北京)有限公司在知识产权领域有了新动作。据天眼查知识产权信息显示,百度已申请多枚“文小言”商标,这些商标将涵盖广告销售、网站服务、健身器材、机械设备等多个领域。
    的头像 发表于 06-19 09:20 484次阅读

    2024百度移动生态万象大会:百度新搜索11%内容已AI生成

    2024百度移动生态万象大会:百度新搜索11%内容已AI生成 今天2024百度移动生态万象大会在江苏苏州举办,特别是AI搜索与百度文心一言的相关信息被市场极度关注,我们看到,在2024
    发表于 05-30 18:58 410次阅读

    百度与特斯拉探讨Robotaxi合作新机遇

    在特斯拉宣布计划使用百度地图提供的高精度地图之后,百度与特斯拉之间的合作再度引起关注。百度自动驾驶技术部总经理徐宝强近日透露,百度正积极考虑与特斯拉在Robotaxi(共享出租车)项目
    的头像 发表于 05-24 10:20 455次阅读

    嵌入式软件工程师和硬件工程师的区别?

    。他们之间的紧密合作对于成功开发出高效的嵌入式系统至关重要。 嵌入式软件工程师和嵌入式硬件工程师在工作中有着不同的技能要求和专业知识。嵌入式软件工程师需要具备扎实的编程基础,熟练掌握C
    发表于 05-16 11:00

    百度智能云正式发布了《百度智能云水业大模型白皮书》

    3月28日,由E20环境平台主办的2024(第二十二届)水业战略论坛在北京召开。会上,百度智能云正式发布了《百度智能云水业大模型白皮书》(以下简称《白皮书》)。
    的头像 发表于 03-29 09:20 1371次阅读
    <b class='flag-5'>百度</b>智能云正式发布了《<b class='flag-5'>百度</b>智能云水业大模型白皮书》

    漳州市长魏东到访百度,与百度智能云共商漳州新质生产力发展

    3月19日,漳州市市长魏东,人大常委会党组成员、副主任蔡总平,副市长洪泰伟一行到访百度亦庄基地,与百度副总裁石清华,百度智能云南区总经理段巍,百度智能云政务创新业务部总经理李琴,围绕漳
    的头像 发表于 03-25 11:27 862次阅读

    百度搜索赵世奇回归,组织架构调整涉及文库等部门

    包括家号业务运营部、热点运营部及内容生态运营管理部在内的多个部门并入信息分发平台,由百度App总经理李小婉指挥。据悉,原百度内容生态平台经理宋健已经离职。
    的头像 发表于 02-23 14:21 891次阅读

    C++简史:C++是如何开始的

    MISRA C++:2023,MISRA® C++ 标准的下一个版本,来了!为了帮助您做好准备,我们介绍了 Perforce 首席技术支持工程师 Frank van den Beuken 博士撰写
    的头像 发表于 01-11 09:00 585次阅读
    <b class='flag-5'>C++</b>简史:<b class='flag-5'>C++</b>是如何开始的