Linux内存管理

来源:互联网 发布:贴吧找图软件 编辑:程序博客网 时间:2024/06/07 01:06
一、页框管理
Linux采用4KB页框大小作为标准的内存分配单元。内核把物理页作为内存管理的基本单位,用struct page结构表示系统中的每个物理页。
1、 非一致内存访问(Non-Uniform Memory Access, NUMA)
给定cpu对不同内存单元的访问时间可能不一样,系统的物理内存被划分为几个节点(node)。在一个单独的节点内,任一给定CPU访问页面所需要的时间都是相同的。
对不同的cpu,这个时间可能不同。每个节点中的物理内存又可以分为几个管理区(zone)。
2、 内存管理区
linux把系统的页划分为区,形成不同的内存池,这样可以根据用途进行分配。
linux主要使用了四个区:ZONE_DMA、ZONE_DMA32、ZONE_NORMAL、ZONE_HIGHMEM
3、 保留的内存池
当有一个内存分配请求:
(1)有足够的空闲内存可用,请求就会被立刻满足;
(2)内存不足,必须回收一些内存,并且将发出请求的内核控制路由阻塞,直到有内存被释放;
(3)当发生在处理中断或在执行临界区内的代码时,内核控制路径不能被阻塞。这种情况下,内核控制路径应当产生原子内存分配请求。
原子请求从不被阻塞,如果没有足够的空闲页,则仅仅是分配失败。
内核为原子分配请求保留了一个页框池,只有在内存不足时才使用。
4、 分区页框分配器:伙伴系统算法,解决外碎片问题
频繁的请求和释放不同大小的一组连续页框,必然导致在已分配页框的块内分散了许多小块的空闲页框。
带来的问题是:即使有足够的空闲页框可以满足请求,但要分配一个大块的连续页框就可能无法满足。
算法:把所有的空闲页框分组为11个块链表,每个块链表分别包含大小为1、2、4、... 、512、1024个连续的页框(2^0 --- 2^10)。

二、内存区管理
伙伴系统算法采用页框作为基本内存区,这适合于对大块内存的请求。对于小内存区的请求(几十或几百字节)分配一个整页框是一种浪费。
取而代之的正确方法是引入一种新的数据结构来描述在同一页框中如何分配小内存区。这就引出了一个新的问题,即所谓的内碎片。
内碎片的产生主要是由于请求内存的大小与分配给它的大小不匹配而造成的。
# slab分配器:解决内碎片问题
高速缓存内存区的大小范围一般包含13个几何分布的内存区。32字节~131072字节,2^5---2^17 Bytes。





三、非连续内存区管理:vmalloc机制,可以避免外碎片,但必须打乱内核页表。
vmalloc的工作方式:
(1)寻找一个新的连续线性地址
(2)依次分配一组非连续的页框
(3)为线性地址空间和非连续页框建立映射关系,即修改内核页表

kmalloc所申请内存的线性地址与物理地址都是连续的。
vmalloc所申请的内存线性地址连续而物理地址是离散的,两个地址之间通过内核页表进行映射。