Linux用户进程是如何释放内存的

Linux进程使用内存的基本流程:

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

那么glibc的堆管理器在什么时候才把物理内存归还给系统呢?

它会从堆的最大线性地址开始,从后向前计算用户任务当前有多少空闲的堆内存(直到碰到使用中的堆内存地址为止),比如在该图中:

它会认为有2048k的可释放内存,只有在该值大于某个特定的threshhold时(2.3.6上为64k),它才会把这些内存归还给系统。而在中间的“未使用”内存是不会归还给系统的,所以系统也不可能再利用这块物理内存页(我们假设系统没有swap区和swap文件),也就是说系统的内存会为此减少,除非在它之前的堆内存都用free进行释放以后,glibc的堆管理器才有可能(只是有可能)把该段内存归还给系统。

由此,我们在使用malloc/free时应该小心,特别是在初始化时分配了好多内存,但是在这之后却再也不需要这么多的内存了,而这块内存又没有达到threshhold值或者在堆的最高线性地址处有某块内存没有释放,但是它前面的所有堆内存都释放了;这种情况下,用户任务将会浪费一些物理内存,这在资源比较紧张的嵌入式系统中是不可容忍的。从图中我们可以看出,进程的堆,并不是直接建立在Linux的内核的内存分配策略上的,而是建立在glibc的堆管理策略上的(也就是glibc的动态内存分配策略上),堆的管理是由glibc进行的。所以我们调用free对malloc得到的内存进行释放的时候,并不是直接释放给操作系统,而是还给了glibc的堆管理实体,而glibc会在把实际的物理内存归还给系统的策略上做一些优化,以便优化用户任务的动态内存分配过程。那么glibc的堆管理器在什么时候才把物理内存归还给系统呢?它会从堆的最大线性地址开始,从后向前计算用户任务当前有多少空闲的堆内存(直到碰到使用中的堆内存地址为止),比如在该图中,它会认为有2048k的可释放内存,只有在该值大于某个特定的threshhold时(2.3.6上为64k),它才会把这些内存归还给系统。而在中间的“未使用”内存是不会归还给系统的,所以系统也不可能再利用这块物理内存页(我们假设系统没有swap区和swap文件),也就是说系统的内存会为此减少,除非在它之前的堆内存都用free进行释放以后,glibc的堆管理器才有可能(只是有可能)把该段内存归还给系统。由此,我们在使用malloc/free时应该小心,特别是在初始化时分配了好多内存,但是在这之后却再也不需要这么多的内存了,而这块内存又没有达到threshhold值或者在堆的最高线性地址处有某块内存没有释放,但是它前面的所有堆内存都释放了;这种情况下,用户任务将会浪费一些物理内存,这在资源比较紧张的嵌入式系统中是不可容忍的。

dustman 回复于:2005-12-28 12:44:501,通过malloc申请的内存并不一定代表实际已经得到的物理内存,而只是改变了用户空间heap空间的大小。2,通过free释放的内存并不一定马上归还给系统,必须是用户heap空间内连续空闲内存数据超出一个阈值时才将这片内存归还给内核。3,如果在用户空间内空闲内存区存在并未达到释放阈值的内存块,并且后续不再申请内存,那么该块内存就将被用户进程“霸占”。是这样理解吗?snow_insky 回复于:2005-12-28 12:50:07目前的Linux堆内存管理是用的ptmalloc的管理方案,在该实现中有个叫做fastbin的东西,好像是用来对分配的内存进行按size分类,比如你分配了一个8byte的内存,在释放的时候如果不能和别人合并,则会缓存起来,链到一个8bytes链中,下次再分配相同大小的内存时,glibc会直接看,在该链中是否有项,如果有,则直接在该链表中摘取一项,返回该项给进程。分配结束!!!!所以glibc的堆管理器已经做了小内存分配的优化动作,我们可以不做了,不过,如果对我们自己的应用有特定需求,则我们也可以再在glibc上包装一层,对小尺寸的内存分配做优化!!snow_insky 回复于:2005-12-28 12:55:31引用:原帖由 dustman 于 2005-12-28 12:44 发表

1,通过malloc申请的内存并不一定代表实际已经得到的物理内存,而只是改变了用户空间heap空间的大小。

2,通过free释放的内存并不一定马上归还给系统,必须是用户heap空间内连续空闲内存数据超出一个阈值时才将这 ...1,3的理解是正确的,但是2可能有点出入,应该是这样的:不是heap空间中有连续的空闲内存数据超过一个阀值时才归还给系统,[color=Red]而是从最后向前测量,直到一个在用的空间为止,如果这段没用的空间总量超过了阀值,则把这段内存归还给系统。[/color]因为系统调用sbrk和brk仅仅只能做的事情是,移动堆的最大线性地址(top memory),它并不能处理中间的空闲空间

snow_insky 回复于:2006-01-05 17:27:33最近看了一些文章,关系到用户栈的设置,顺便在这里发给大家!目前用户态栈是放在3G空间的下面,默认的情况下是8M,我们可以通过一些方法来改变栈的位置。如:你写一个函数,在该函数中声明一个静态变量static stack[8M], 然后移动栈指针asm ("movl %0, %%esp\n" : : "a" (stack + sizeof(stack)));我们就得到了一个新的堆栈。呵呵大家可以试试!zhhhuang 回复于:2006-01-06 14:32:46请教个问题, 我写了个程序,发现每次分配10K内存后,显示堆内存数量(VmData)增加8K或12K(cat /proc/pid/status ),12K可以理解,为什么有时候会是8K?而且8K和12K不是交错增加的,有时malloc 10K好几次,但都是增加8K。思一克 回复于:2006-01-06 14:58:3710K,是2页半。物理分配按页。12K, 3 PAGES下次,分8K即可,加上上次空闲的半PAGE引用:原帖由 zhhhuang 于 2006-1-6 14:32 发表

请教个问题, 我写了个程序,发现每次分配10K内存后,显示堆内存数量(VmData)增加8K或12K(cat /proc/pid/status ),12K可以理解,为什么有时候会是8K?而且8K和12K不是交错增加的,有时malloc 10K好几次,但都 ...zhhhuang 回复于:2006-01-06 15:33:55有时malloc 10K好几次,但都是增加8K?snow_insky 回复于:2006-01-06 15:44:34呵呵,这难道不是正常的吗? 思一克    已经说得很清楚了啊物理页面是按照4K的页管理的,为了效率,我们的虚拟地址空间也是按照4K大小为单位的页进行管理的,你第一次分配10K,它应该会增加12K,然后你再分配10K的时候,由于有2K的空闲,它只需增加8K就能满足你的需求了啊!干嘛,还不满意,认为内核亏待你了???呵呵,开玩笑!zhangjiakouzf 回复于:2006-01-08 12:02:58如果在系统内存耗尽的情况下,GLIBC会不会对进程没有使用并且也没有归还系统的内存块进行操作?我在服务器上面看到的情况是,系统内存一直消耗到剩余8M左右就不会在消耗了!但所有进程的内存使用量之和要小于在TOP中看到的被使用的内存总数,是不是楼主说的原因呀,那么到剩余8M以后会发生什么事情呀,期待中richardhesidu 回复于:2006-01-08 12:17:10引用:原帖由 zhangjiakouzf 于 2006-1-8 12:02 发表

如果在系统内存耗尽的情况下,GLIBC会不会对进程没有使用并且也没有归还系统的内存块进行操作?

我在服务器上面看到的情况是,系统内存一直消耗到剩余8M左右就不会在消耗了!但所有进程的内存使用量之和要小于在TO ...首先,由于linux用了cow技术,所以内存透支是允许存在的。如果系统内存真正耗尽,下面要做的事就不是glibc能做的了。内核有一个OOM killer,在内存耗尽的时候会挑选一个进程杀死,来获得内存。不过现在的系统内存大多很大,所以OOM killer的作用不大。snow_insky 回复于:2006-01-08 20:47:59引用:原帖由 zhangjiakouzf 于 2006-1-8 12:02 发表

如果在系统内存耗尽的情况下,GLIBC会不会对进程没有使用并且也没有归还系统的内存块进行操作?

我在服务器上面看到的情况是,系统内存一直消耗到剩余8M左右就不会在消耗了!但所有进程的内存使用量之和要小于在TO ...首先:要说明的是,你用top观察的结果是不准确的,因为有共享库的存在,所以你可能重复计算;其次:glibc是不会帮忙系统处理内存紧张情况的,因为它也只不过是一个共享库而已,所不同的是,它是所有应用程序都需要的(当然,你也可以通过一定的方式,来让你的应用程序不使用glibc)再次:你所看到的进程消耗的内存小于top的观察值是因为,你需要加上buffer和cache的值,才能基本等于top中所观察到的内存使用量。不知道这些解释,你能不能明白,如果不行,我们再继续,呵呵!下次我会说明free命令的内容的含义!snow_insky 回复于:2006-01-08 20:56:23还有一点忘记说了,你的系统空闲内存停留在8M左右,是因为,你的buffer和cache已经达到了一定的值,不需要再增加了,所以你会发现它停在那里。还有,你执行如下命令: cat /proc/sys/vm/kswapd,你会看到你的系统保留的空闲内存的阀值,具体涵义,你可以搜索一下它的涵义。richardhesidu :并不是如你所说,所有的系统都有很多内存,你没有考虑到嵌入式系统的应用。我们的产品实现很多功能,但只有32M内存,呵呵,难啊!我们正在做内存优化,所以做了好多工作,并会逐步拿出来和大家分享。

linux 进程堆管理,对Linux堆内存释放的总结相关推荐

  1. Linux进程退出详解(do_exit)--Linux进程的管理与调度(十四)

    Linux进程的退出 linux下进程退出的方式 正常退出 从main函数返回return 调用exit 调用_exit 异常退出 调用abort 由信号终止 _exit, exit和_Exit的区别 ...

  2. 操作系统实验报告linux进程管理,计算机操作系统实验报告三Linux进程基本管理.doc...

    GDOU-B-11-112广东海洋大学学生实验报告书(学生用表) GDOU-B-11-112 实验名称 Linux进程基本管理 课程名称 计算机操作系统 课程号 学院(系) 专业 统 班级 学生姓名 ...

  3. Linux进程调度器概述--Linux进程的管理与调度(十五)

    日期 内核版本 架构 作者 GitHub CSDN 2016-06-14 Linux-4.6 X86 & arm gatieme LinuxDeviceDrivers Linux进程管理与调度 ...

  4. linux 进程装入 物理内存 页表,linux内存管理解析----linux物理,线性内存布局及页表的初始化...

    主要议题: 1分页,分段模式及实模式 2Linux分页 3linux内存线性地址空间布局及物理内存空间布局 4linux页表初始化及代码解析 1.1.1内存寻址和保护模式 在X86平台上,内存控制单元 ...

  5. Linux进程描述符task_struct结构体详解--Linux进程的管理与调度(一)

    转自:http://blog.csdn.net/gatieme/article/details/51383272 日期 内核版本 架构 作者 GitHub CSDN 2016-05-12 Linux- ...

  6. Linux进程描述符task struct结构体详解--Linux进程的管理与调度(一)

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 日期 内 ...

  7. Linux下1号进程的前世(kernel_init)今生(init进程)----Linux进程的管理与调度

    Linux下有3个特殊的进程,idle进程(PID=0PID=0), init进程(PID=1PID=1)和kthreadd(PID=2PID=2) * idle进程由系统自动创建, 运行在内核态 i ...

  8. Linux下0号进程的前世(init_task进程)今生(idle进程)----Linux进程的管理与调度(五)【转】...

    前言 Linux下有3个特殊的进程,idle进程(PID = 0), init进程(PID = 1)和kthreadd(PID = 2) idle进程由系统自动创建, 运行在内核态 idle进程其pi ...

  9. Linux内核线程kernel thread详解--Linux进程的管理与调度(十)【转】

    转自:https://blog.csdn.net/gatieme/article/details/51589205 版权声明:本文为博主原创文章 && 转载请著名出处 @ http:/ ...

  10. Linux进程调度策略的发展和演变--Linux进程的管理与调度(十六)

    日期 内核版本 架构 作者 GitHub CSDN 2016-06-14 Linux-4.6 X86 & arm gatieme LinuxDeviceDrivers Linux进程管理与调度 ...

最新文章

  1. 2.4g 无线键鼠对码软件_无线路由器的2.4G和5G同时开速度有影响吗?
  2. rust(33)-Rust and WebAssembly(1)
  3. C#字符串的基本操作
  4. 蓝桥杯 作物杂交 DFS搜索
  5. Echarts地图编写
  6. 上海往事之参加安永公司项目面试
  7. 数字化转型案例:美的集团
  8. 关于黑马JavaWeb教程注册登录案例报错
  9. ggggxc学习笔记----Vue学习笔记II----模板语法
  10. DEDECMS专题制作
  11. SHA1 简单介绍以及使用
  12. 【2023最新】Git安装配置教程
  13. bbr中的缩放因子BW_SCALE/BBR_SCALE
  14. 【锐捷交换】接入交换机配置DHCP Snooping + IP Source guard + ARP-check
  15. 手机卡变了 发短消息通知
  16. 计算机中ar的作用,AR增强现实的作用
  17. [CF3B]Lorry
  18. 为什么要抛弃maven
  19. 神秘“鬼影”病毒袭击Winxp系统,重装也无法消灭
  20. Python编程练习(三):21 - 30

热门文章

  1. BBQ EasyBuns
  2. iqooz6和z5哪个好 iqoo z6和iqoo z5哪个更值得入手
  3. BZOJ 4987 (树形DP)
  4. python 文件读取
  5. 学习笔记(13):21天通关Python(视频课)-字典高级用法
  6. python:实现base64加密和base64解密算法(附完整源码)
  7. Could not find a price list in Ordered UOM xxx and Primary UOM of the item
  8. MTK DDR进行ETT之后的压力测试--进行压力测试
  9. 企鹅F4手机外观设计有突破 配MTK6592八核处理器
  10. mysql横切竖切_MySQL常用操作 - cheney-f的个人空间 - OSCHINA - 中文开源技术交流社区...