对Linux堆内存释放的总结

转载 2012年03月25日 20:30:24
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值或者在堆的最高线性地址处有某块内存没有释放,但是它前面的所有堆内存都释放了;这种情况下,用户任务将会浪费一些物理内存,这在资源比较紧张的嵌入式系统中是不可容忍的。


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

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


 
原文:http://www.chinaunix.net/jh/4/677609.html

对Linux堆内存释放的总结

http://bbs.chinaunix.net/thread-2195511-1-1.html Linux用户进程是如何释放内存的 Linux进程使用内存的基本流程:   从图中我们可以看出,进程的...
  • haichunzhao
  • haichunzhao
  • 2014年03月04日 17:03
  • 1997

进程终结后, 泄露的堆内存会自动释放吗?

看来个问题, 进程终结后, 泄露的堆内存会自动释放吗?        当然会!  这些堆内存都是与进程生死相关的。 所以, 在很多时候:        1. 重启后台服务是可以释放泄露的内存的, 可以...
  • stpeace
  • stpeace
  • 2017年04月02日 17:43
  • 2936

[图]Linux堆内存释放的总结

[图]Linux堆内存释放的总结蓝森林 http://www.lslnet.com 2006年4月6日 21:05 Linux用户进程是如何释放内存的 Linux进程使用内存的基本流程: 见...
  • gothicane
  • gothicane
  • 2007年12月18日 13:25
  • 826

动态内存空间的开辟与释放

在不知道需要占用内存空间大小时,需要在堆栈上动态开辟内存空间,空间使用结束后需要程序员自己释放。#include #include void main() { int n,*p,i,j,m,...
  • yangshuangtao
  • yangshuangtao
  • 2015年04月22日 16:36
  • 724

C++【堆内存的动态分配与释放(new/delete)】

C语言分配动态内存常用函数:malloc/calloc/realloc/free C++语言用new/delete:详见memory.cpp 1.通过new运算符分配单个变量 数据类型* 指针变...
  • u010193457
  • u010193457
  • 2015年10月28日 10:59
  • 1691

释放堆内存

TInt UseCat(CCat* aCat); // Forward declarationCCat* InitializeCatL(){CCat* cat = new(ELeave) CCat()...
  • liutaotao0622
  • liutaotao0622
  • 2009年06月16日 19:10
  • 290

C/C++申请和释放内存

new 和 delete 是 C++ 用于管理堆内存的两个运算符,对应于C语言中的 malloc 和 free,但是 malloc 和 free 是函数,而new 和 delete 是运算符。除此之外...
  • dongxianfei
  • dongxianfei
  • 2018年01月11日 11:39
  • 91

内存管理面试题 (内存没有立即释放,造成内存堆积)

问:这段代码是否合理?如果不合理,给出修改意见. @autoreleasepool {     for (int i = 0; i             Person *per = [[Pe...
  • GCZtian
  • GCZtian
  • 2015年01月03日 21:03
  • 915

销毁资源和释放内存

0. 什么是资源? .NET 框架中如何访问资源? 所谓的资源就是程序中可利用的数据,譬如:字符串、图片和任何二进制数据,包括任何类型的文件。 在面向对象的环境中,每一个类型都标识为某些程序所用的...
  • xipan10102232
  • xipan10102232
  • 2015年04月28日 09:12
  • 712

c++五种内存分配、堆与栈区别

在C++中,内存分成5个区,他们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。    栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清楚的变量的存储区。里面的变量通常是局部变量、函...
  • mfreesky
  • mfreesky
  • 2008年03月26日 10:44
  • 3902
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:对Linux堆内存释放的总结
举报原因:
原因补充:

(最多只允许输入30个字)