linux内存管理
虚拟内存空间的管理
- linux操作系统采用的是请求式分页虚拟内存管理
- 每个进程有独立的4GB的虚拟内存空间
IA32体系结构具有两种内存管理模式:
实模式
保护模式
- 逻辑地址到物理地址的转换:
- 逻辑地址——>线性地址(虚拟地址)——>物理地址
- 内核空间到物理内存的映射
- 内核空间由所有进程共享,存放着内核代码和数据
- 内核空间映射到物理内存总是从最低地址开始,建立线性关系
- 系统启动时,内核映像被装载到物理地址1MB开始的地方
进程用户空间
linux把进程的用户空间划分成一个个区间。
- 一个进程的用户进程空间由mm_struct结构描述(对进行的整个用户空间进行描述,memory descriptor)
- vm_area_struct结构是虚存空间的一个连续区域,所有的该结构体组成一个单链表,在这个区域里的信息具有相同的操作和访问特性。vm_mm指针指向mm_struct结构体;vm_strart和vm_end是虚拟区域的开始和终止地址
创建进程用户空间
- 通过fork()系统调用,在创建新进程的同时,也为该进程创建完整的用户空间
- 新进程的用户空间——copy_mm(),通过写时复制技术创建的
linux的分页内存管理机制
linux总是假定处理器支持三级页表结构(对于IA32,把PGD和PMD合二为一):
- 页目录PGD
- 页中间目录PMD
- 页表PTE
内核2.6.11之后采用四级页表模型
- 线性地址到物理地址映射(以IA32为例)
- 页目录:高10位
- 页表:中间10位
- 偏移:低12位,用来表示在一个页帧中的偏移
- 每个进程都有一个页目录。由寄存器CR3指向该页目录的基地址
- 缺页异常:
- 编程错误
- 操作系统故意引发的异常
- 缺页异常的处理程序是do_page_fault()函数:该函数有两个参数:一个是发送异常地址;一个是错误码;
- do_page_fault()执行过程:从CR2得到发送异常的线性地址;使用LRU去换页,为每个页面设置一个age,年纪越大,越容易被换
- 交换机制:当物理内存小于一个固定的极限时,就会执行换出操作
物理内存的管理
定义
页帧:物理内存是以页帧为基本单位的,IA32为4kb
结点:访问速度相同的一个内存区域,与处理器相关联
zone:根据用途不同,将不同结点的物理内存分成不同的zone
linux对于zone曹勇buddy system管理
page结构
页帧是由page结构体表示的。
物理内存的分配和回收
- buddy分配
物理内存采用的是buddy分配算法,最小的分配单位是页帧,目的是分配一组连续的物理页帧。
buddy:两组连续的页帧,满足——大小相同;物理地址连续;第2个页块后面的页帧必须是2n的倍数。
buddy算法把内存中的所有页帧按照2^n划分,分成1,2,4,8.。。。。1024一共11种页块,每个页块组用一个双向循环链表进行管理,也就是一共有11个链表
比如free_area[0]指向1页帧块的链表
比如free_area[2]指向4页帧块的链表
- 内存回收
- 回收时需要检查与该页帧相邻的空闲页块,若存在则需要合成一个连续的空闲区,按buddy算法重新分组
- slab分配器
- 为了解决buddy算法以页帧为基本分配单位可能造成的内部碎片
- 基本思想:为经常使用的小对象建立缓冲,小对象的申请和释放由slab分配器管理,不与buddy系统打交道