Linux是如何避免内存碎片的?
在网上看到这个面试题,参考答案是这样的:
- 伙伴算法,用于管理物理内存,避免内存碎片;
- 高速缓存Slab层用于管理内核分配内存,避免碎片。
故继而去深入了解了一波,做了一个粗略的整理:
内存碎片问题
- 频繁地请求和释放不同大小的内存,必然导致内存碎片问题的产生,结果就是当再次要求分配连续的内存时,即使整体内存是足够的,也无法满足连续内存的需求。该问题也称之为外碎片(external fragmentation)。
- 解决方案:
- 避免外碎片的方法有两种:
1、利用分页单元把一组非连续的空闲页框映射到连续的线性地址
2、开发一种适当的技术来记录现存的空闲的连续页框块的情况,以尽量避免为满足对小块的请求而分割大的空闲快 - 第一种方案的意思是,我们使用地址转换技术,把非连续的物理地址转换成连续的线性地址。
- 第二种方案的意思是,开发一种特有的分配技术来记录下来空闲内存的情况,从而解决内存碎片问题。
- Linux采用了第二种方案,因为在某些情况下,系统的确需要连续的物理地址(DMA处理器可以直接访问总线)。
这里先对Linux内存管理做一个简单介绍
- linux kernel 通过把整个物理内存划分成以一个个page进行管理,管理器就是伙伴系统,它的最小分配单元就是page。但是对于小于page的内存分配,如果直接分配一个page,是一个很大的浪费。linux kernel 通过slab来实现对小于page大小的内存分配。slab把page按2的m次幂进行划分一个个字节块,当kmalloc申请内存时,通过slab管理器返回需要满足申请大小的最小空闲内存块。
- slub主要是针对slab的对象管理数据的优化版本,相比于slab,slub提供