当前位置:网站首页>内存申请(malloc)和释放(free)之下篇
内存申请(malloc)和释放(free)之下篇
2022-08-02 14:07:00 【lq_fly_pig】
上篇介绍了内存malloc的sbrk和brk系统调用,以及mmap函数。本篇开始学习下内存的具体的malloc分配逻辑和free逻辑。(本篇幅的学习借助,华庭大神(阿里 庄明强) 总结的ptmalloc源码资料)
1.简介
linux系统glibc库是linux系统中最底层的c语言运行库,glibc库中分配内存和释放内存使用的函数是ptmalloc函数和free函数,分配器处在用户程序和内核之间,响应用户的内存分配请求。为了高效分配,分配器一般会预先分配一块大于用户请求的内存,并通过某些算法来管理这块内存,来满足用户的内存申请,当然 用户free内存的时候,也不是立即归还给OS操作系统,也是分配器通过一些算法管理这些空闲的内存,以便于下次申请内存,直接复用,提高内存的使用效率。
2.ptmalloc设计假设
Ptmalloc在设计时候折中效率,高空间利用率、高可用设计目标,其设计代码中存在内存管理的一些假设:
(1).具有长生命周期的或者特大块内存分配,采用mmap方法,主要是mmap映射匿名页面,当发生缺页中断时,linux内核会缺页分分配一个新的物理页面,并将改物理页面清0,一个mmap需要多个页面映射,导致多次清0操作,浪费系统资源。故引入动态阈值调整机制,分配的内存大于一定值,才使用mmap函数申请内存。
(2).具有短生命周期、内存大小较小的内存使用brk分配
(3).尽量只缓存临时使用的空闲小内存块,对大内存块或是长生命周期的大内存块在释放时都直接归还给操作系统。
(4).对空闲小内存块只会在malloc和free时候才进行合并,free空闲的内存块可能放入pool中,不一定还给操作系统
(5).收缩堆的条件是 当前free的内存块大小加上前后合并的chunk内存大小大于64kB(32位系统),并且堆顶的大小达到阈值,才能收缩堆,把堆最顶端的空闲的内存返回给操作系统
(6).内存碎片产生:多线程可以从同一个分配区中分配内存,线程A释放一块内存后,线程B会申请内存,大小和A申请的大小不一样,或许是一个小的差别。就需要对内存块进行不停的分割和合并操作,这个过程可能会存在内存碎片
下面结合几个图来理解下:
第一步:开辟内存,A=40k, B= 50k,D= 60K,C=128K,由于C=128K 大于mmap默认大小,故使用mmap开辟内存
第二步: 如上右图所示,malloc(E) 且 E= 100k 小于128K,故使用brk分配内存,移动brk指针,从堆空间中分配内存。
第三部:释放A空间,free(A),接着开辟30k内存,malloc(30k)
free(A)后,A的内存块不会立马归还给操作系统,此时给A内存块打上标记,表示改内存处于空闲状态。此时如果系统再次分配30k的内存时,查询到有40k的内存块处于空闲状态,会把40K内存分割成30K和10K,重用30k内存大小,剩余的10K 暂且会搁置。后面如果不能合并,也不能被重用,就会形成内存碎片
第四步:free(C), C= 128k, free(D) D=60K
由于C=128K,free(C) 会调用mummap()直接释放内存块,归还给操作系统。free(D),D=60K,此时由于D和A=40k内存,地址空间不连续,故不能合并,会存在由上图情况,存在两块空闲内存。
第五步: free(E) E=100k
free(E),E=100k,如上左图 E=100k 和60k地址连续,会合并形成160K大小的内存,大于默认值(128K),且内存靠近堆顶指针,sbrk回溯,此时内存归还给os操作系统
未完待续。。。
边栏推荐
猜你喜欢
随机推荐
redis基础
2022最新交规记忆重点
VS Code远程开发及免密配置
MySQL知识总结 (六) MySQL调优
uniCloud 未能获取当前用户信息:30205 | 当前用户为匿名身份
spark写sql的方式
PostgreSQL 性能谜题
再见篇:App专项技术优化
自定义圆形seekBar,超简单
AAPT: error: duplicate value for resource ‘attr/xxx‘ with config ‘‘, file failed to compile.
Kubernetes介绍
【目标检测】YOLO v5 安全帽检测识别项目模型
kotlin Android序列化
MySQL知识总结 (二) 存储引擎
数据的表示方法和转换(二进制、八进制、十进制、十六进制)
2. Basic use RecyclerView
宝塔搭建PESCMS-Ticket开源客服工单系统源码实测
Visual studio代码中有红色波浪线解决办法
什么是闭包?闭包的作用?闭包的应用?有什么缺点?
Flink依赖汇总