全部博文(930)
分类: LINUX
2009-08-15 10:07:42
堆内存释放的奥秘
文件:
Linux堆内存释放的总结.rar
大小:
33KB
下载:
下载
从图中我们可以看出,进程的堆,并不是直接建立在Linux的内核的内存分配策略上的,而是建立在glibc的堆管理策略上的(也就是glibc的动态内存分配策略上),堆的管理是由glibc进行的。
所以我们调用free对malloc得到的内存进行释放的时候,并不是直接释放给操作系统,而是还给了glibc的堆管理实体,而glibc会在把实际的物理内存归还给系统的策略上做一些优化,以便优化用户任务的动态内存分配过程。
那么glibc的堆管理器在什么时候才把物理内存归还给系统呢?
它会从堆的最大线性地址开始,从后向前计算用户任务当前有多少空闲的堆内存(直到碰到使用中的堆内存地址为止),比如在该图中,
它会认为有2048k的可释放内存,只有在该值大于某个特定的threshhold时(
由此,我们在使用malloc/free时应该小心,特别是在初始化时分配了好多内存,但是在这之后却再也不需要这么多的内存了,而这块内存又没有达到threshhold值或者在堆的最高线性地址处有某块内存没有释放,但是它前面的所有堆内存都释放了;这种情况下,用户任务将会浪费一些物理内存,这在资源比较紧张的嵌入式系统中是不可容忍的。
关于碎片的问题:
目前的Linux堆内存管理是用的ptmalloc的管理方案,在该实现中有个叫做fastbin的东西,好像是用来对分配的内存进行按size分类,比如你分配了一个8byte的内存,在释放的时候如果不能和别人合并,则会缓存起来,链到一个8bytes链中,下次再分配相同大小的内存时,glibc会直接看,在该链中是否有项,如果有,则直接在该链表中摘取一项,返回该项给进程。分配结束!!!!
所以glibc的堆管理器已经做了小内存分配的优化动作,我们可以不做了,不过,如果对我们自己的应用有特定需求,则我们也可以再在glibc上包装一层,对小尺寸的内存分配做优化!!
两个图不知道怎么贴不少,我的Word文档如下,NND变成如下了,难得调了