免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
1234下一页
最近访问板块 发新帖
查看: 12379 | 回复: 32

对Linux堆内存释放的总结 [复制链接]

论坛徽章:
0
发表于 2005-12-27 17:56 |显示全部楼层
今天上午得到了该版的一些高手指点,终于弄懂了堆内存释放的奥秘,特总结出来与大家分享!


Linux用户进程是如何释放内存的
Linux进程使用内存的基本流程:

C:\Documents and Settings\eric\My Documents\Linux用户进程是如何使用内存的.doc
从图中我们可以看出,进程的堆,并不是直接建立在Linux的内核的内存分配策略上的,而是建立在glibc的堆管理策略上的(也就是glibc的动态内存分配策略上),堆的管理是由glibc进行的。
所以我们调用free对malloc得到的内存进行释放的时候,并不是直接释放给操作系统,而是还给了glibc的堆管理实体,而glibc会在把实际的物理内存归还给系统的策略上做一些优化,以便优化用户任务的动态内存分配过程。

那么glibc的堆管理器在什么时候才把物理内存归还给系统呢?
它会从堆的最大线性地址开始,从后向前计算用户任务当前有多少空闲的堆内存(直到碰到使用中的堆内存地址为止),比如在该图中,
它会认为有2048k的可释放内存,只有在该值大于某个特定的threshhold时(2.3.6上为64k),它才会把这些内存归还给系统。而在中间的“未使用”内存是不会归还给系统的,所以系统也不可能再利用这块物理内存页(我们假设系统没有swap区和swap文件),也就是说系统的内存会为此减少,除非在它之前的堆内存都用free进行释放以后,glibc的堆管理器才有可能(只是有可能)把该段内存归还给系统。

由此,我们在使用malloc/free时应该小心,特别是在初始化时分配了好多内存,但是在这之后却再也不需要这么多的内存了,而这块内存又没有达到threshhold值或者在堆的最高线性地址处有某块内存没有释放,但是它前面的所有堆内存都释放了;这种情况下,用户任务将会浪费一些物理内存,这在资源比较紧张的嵌入式系统中是不可容忍的。


谢谢!

论坛徽章:
0
发表于 2005-12-27 17:59 |显示全部楼层

不能贴图片:

Linux用户进程是如何释放内存的
Linux进程使用内存的基本流程:
    见图1
从图中我们可以看出,进程的堆,并不是直接建立在Linux的内核的内存分配策略上的,而是建立在glibc的堆管理策略上的(也就是glibc的动态内存分配策略上),堆的管理是由glibc进行的。
所以我们调用free对malloc得到的内存进行释放的时候,并不是直接释放给操作系统,而是还给了glibc的堆管理实体,而glibc会在把实际的物理内存归还给系统的策略上做一些优化,以便优化用户任务的动态内存分配过程。

那么glibc的堆管理器在什么时候才把物理内存归还给系统呢?
它会从堆的最大线性地址开始,从后向前计算用户任务当前有多少空闲的堆内存(直到碰到使用中的堆内存地址为止),比如在该图中,
    见图2
它会认为有2048k的可释放内存,只有在该值大于某个特定的threshhold时(2.3.6上为64k),它才会把这些内存归还给系统。而在中间的“未使用”内存是不会归还给系统的,所以系统也不可能再利用这块物理内存页(我们假设系统没有swap区和swap文件),也就是说系统的内存会为此减少,除非在它之前的堆内存都用free进行释放以后,glibc的堆管理器才有可能(只是有可能)把该段内存归还给系统。

由此,我们在使用malloc/free时应该小心,特别是在初始化时分配了好多内存,但是在这之后却再也不需要这么多的内存了,而这块内存又没有达到threshhold值或者在堆的最高线性地址处有某块内存没有释放,但是它前面的所有堆内存都释放了;这种情况下,用户任务将会浪费一些物理内存,这在资源比较紧张的嵌入式系统中是不可容忍的。


谢谢!

图1

图1

图2

图2

论坛徽章:
84
每日论坛发贴之星
日期:2015-12-29 06:20:00每日论坛发贴之星
日期:2016-01-16 06:20:00每周论坛发贴之星
日期:2016-01-17 22:22:00程序设计版块每日发帖之星
日期:2016-01-20 06:20:00每日论坛发贴之星
日期:2016-01-20 06:20:00程序设计版块每日发帖之星
日期:2016-01-21 06:20:00每日论坛发贴之星
日期:2016-01-21 06:20:00程序设计版块每日发帖之星
日期:2016-01-23 06:20:00程序设计版块每日发帖之星
日期:2016-01-31 06:20:00数据库技术版块每日发帖之星
日期:2016-01-16 06:20:00程序设计版块每日发帖之星
日期:2016-01-16 06:20:00程序设计版块每日发帖之星
日期:2016-01-14 06:20:00
发表于 2005-12-28 10:34 |显示全部楼层
原来是这样! 谢谢,谢谢!

招聘 : c/c++研发
论坛徽章:
0
发表于 2005-12-28 11:46 |显示全部楼层
前几天都在商量malloc的内存碎片问题,原来是这样的
up

论坛徽章:
0
发表于 2005-12-28 12:44 |显示全部楼层
1,通过malloc申请的内存并不一定代表实际已经得到的物理内存,而只是改变了用户空间heap空间的大小。
2,通过free释放的内存并不一定马上归还给系统,必须是用户heap空间内连续空闲内存数据超出一个阈值时才将这片内存归还给内核。
3,如果在用户空间内空闲内存区存在并未达到释放阈值的内存块,并且后续不再申请内存,那么该块内存就将被用户进程“霸占”。

是这样理解吗?

论坛徽章:
0
发表于 2005-12-28 12:50 |显示全部楼层

关于malloc碎片的问题

目前的Linux堆内存管理是用的ptmalloc的管理方案,在该实现中有个叫做fastbin的东西,好像是用来对分配的内存进行按size分类,比如你分配了一个8byte的内存,在释放的时候如果不能和别人合并,则会缓存起来,链到一个8bytes链中,下次再分配相同大小的内存时,glibc会直接看,在该链中是否有项,如果有,则直接在该链表中摘取一项,返回该项给进程。分配结束!!!!

所以glibc的堆管理器已经做了小内存分配的优化动作,我们可以不做了,不过,如果对我们自己的应用有特定需求,则我们也可以再在glibc上包装一层,对小尺寸的内存分配做优化!!

论坛徽章:
0
发表于 2005-12-28 12:55 |显示全部楼层
原帖由 dustman 于 2005-12-28 12:44 发表
1,通过malloc申请的内存并不一定代表实际已经得到的物理内存,而只是改变了用户空间heap空间的大小。
2,通过free释放的内存并不一定马上归还给系统,必须是用户heap空间内连续空闲内存数据超出一个阈值时才将这 ...


1,3的理解是正确的,但是2可能有点出入,应该是这样的:

不是heap空间中有连续的空闲内存数据超过一个阀值时才归还给系统,而是从最后向前测量,直到一个在用的空间为止,如果这段没用的空间总量超过了阀值,则把这段内存归还给系统。

因为系统调用sbrk和brk仅仅只能做的事情是,移动堆的最大线性地址(top memory),它并不能处理中间的空闲空间

论坛徽章:
0
发表于 2005-12-28 13:35 |显示全部楼层
谢了

收藏

论坛徽章:
0
发表于 2005-12-30 10:38 |显示全部楼层

想知道用户程序堆栈的管理

如题,以及在哪里做堆栈的限制

论坛徽章:
0
发表于 2006-01-05 10:58 |显示全部楼层
好东西!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP