linux内存管理

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系统打交道