转自:http://blog.csdn.net/ycnian/article/details/12971863缓存
咱们写过不少C程序了,常常会分配内存。记得刚学C语言时老师说过,能够向两个地方申请内存:一个是栈、一个是堆。小块内存向栈申请,函数调用结束后程序会自动释放内存。大块内存向堆申请,记得必定要本身释放,不然会形成内存泄漏。向堆申请内存直接调用malloc()就能够了,参数是你申请的内存量。释放内存时直接调用free()就能够了,参数是内存块指针。多线程
看似平静的海面,海底则波涛汹涌。当时尚未学操做系统原理,更没有读过Linux内核代码。如今仔细想一想才发现申请动态内存是一件多么麻烦的事情。动态内存管理涉及到两个层面的问题:内核层面和用户层面。系统中的内存如何管理这是内核考虑的事情,总不能让应用程序随便使用系统中的内存吧。内核向应用程序提供了接口(为此Linux提供了两个系统调用brk和mmap),当应用程序须要申请内存时向内核提出请求,内核查找并分配一块可用内存供应用程序使用。这部份内容属于内核范畴,不属于C基础库,所以不深刻说了。那么用户层面作什么呢?用户层面须要合理管理内存申请和释放请求。好比:brk()能够扩充或收缩堆的大小,你总不能每分配一次内存就调用一次brk()吧?释放内存时更麻烦,你必须保证内存块的释放顺序。好比先申请了内存块a,而后申请了内存块b,而后释放a(b仍然在使用),若是释放a时调用了brk()就会出问题。你不能在使用b的同时释放a。函数
好在出现了一个叫作“内存分配器”的东西,内存分配器接管了应用程序申请内存和释放内存的请求,应用程序不再须要直接调用brk()和mmap()了,而是向内存分配器提交申请。有了内存分配器,咱们只须要记住malloc()和free()两个接口函数就能够了,其余繁杂事情所有交给内存分配器负责了。申请内存时,内存分配器会一次向内核申请大量内存,而后分批交给应用程序,从而提升了效率。释放内存时,应用程序也是将内存释放给内存分配器,内存分配器在合适的时候再将内存释放会内核。spa
dlmalloc就是一种内存分配器,由Doug Lea在1987年开发完成,这是Android系统中使用的内存分配器。而Linux系统中采用的是ptmalloc,ptmalloc在dlmalloc的基础上进行了改进,以更好适应多线程。dlmalloc采用两种方式申请内存,若是应用程序单次申请的内存量小于256kb,dlmalloc调用brk()扩展进程堆空间,可是dlmalloc向内核申请的内存量大于应用程序申请的内存量,申请到内存后dlmalloc将内存分红两块,一块返回给应用程序,另外一块做为空闲内存先保留起来。下次应用程序申请内存时dlmalloc就不须要向内核申请内存了,从而加快内存分配效率。当应用程序调用free()释放内存时,若是内存块小于256kb,dlmalloc并不立刻将内存块释放回内存,而是将内存块标记为空闲状态。这么作的缘由有两个:一是内存块不必定能立刻释放会内核(好比内存块不是位于堆顶端),二是供应用程序下次申请内存使用(这是主要缘由)。当dlmalloc中空闲内存量达到必定值时dlmalloc才将空闲内存释放会内核。若是应用程序申请的内存大于256kb,dlmalloc调用mmap()向内核申请一块内存,返回返还给应用程序使用。若是应用程序释放的内存大于256kb,dlmalloc立刻调用munmap()释放内存。dlmalloc不会缓存大于256kb的内存块,由于这样的内存块太大了,最好不要长期占用这么大的内存资源。操作系统
从下篇文章开始,咱们将详细讲解dlmalloc的代码,环境是Linux 32位系统。.net