第四章 内存管理
vm_avl_height,这3个域在一起构成AVL树,其中vm_avl_height是 , 个域在一起构成AVL树 其中 AVL 是 vm_avl_left, 该节点距根节点的高度,vm_avl_left和 和 , 该节点距根节点的高度, vm_avl_right vm_avl_right分别是该节点的左右两个子树。 分别是该节点的左右两个子树。 Vm_ops 对虚存区进行操作的函数。 对虚存区进行操作的函数。这些给出了可以对虚存 区中的页所进行的操作。 区中的页所进行的操作。
网络工程系 曾令明
虚拟内存实现机制及之间的关系
地址映射
网络工程系 曾令明
虚拟内存实现机制及之间的关系
进程的用户空间管理
• 每个进程经编译、链接后形成的二进制映像 每个进程经编译、 文件有一个代码段和数据段 • 进程运行时须有独占的堆栈空间
堆栈段 空洞 数据段 代码段 进程的用户空 间(3G) )
arg_start, arg_end, env_start, env_end rss, total_vm, locked_vm mmap
命令行参数所在的堆栈部分的起始地址和终 止地址; 止地址; 环境串所在的堆栈部分的起始地址和终止地 址 进程贮留在物理内存中的页面数, 进程贮留在物理内存中的页面数,进程所需 的总页数,被锁定在物理内存中的页数。 的总页数,被锁定在物理内存中的页数。 vm_area_struct虚存区结构形成一个单链表, vm_area_struct虚存区结构形成一个单链表, 虚存区结构形成一个单链表 其基址由小到大排列 vm_area_struct虚存区结构形成一个颗AVL平 vm_area_struct虚存区结构形成一个颗AVL平 虚存区结构形成一个颗AVL 衡树 最近一次用到的虚存区很可能下一次还要用 因此, 到,因此,把最近用到的虚存区结构放入高 速缓存,这个虚存区就由mmap_cache指向。 mmap_cache指向 速缓存,这个虚存区就核空间到物理内存的映射
• 内核空间由所有进程共享,其中存放的是内 内核空间由所有进程共享, 核代码和数据, 内核映象” 核代码和数据,即“内核映象” • 进程的用户空间中存放的是用户程序的代码 和数据 • 内核空间映射到物理内存总是从最低地址 (0x00000000)开始,使之在内核空间 )开始, 与物理内存之间建立简单的线性映射关系。 与物理内存之间建立简单的线性映射关系。
网络工程系 曾令明
网络工程系 曾令明
struct vm_operations_struct { void (*open)(struct vm_area_struct * area); void (*close)(struct vm_area_struct * area); struct page * (*nopage)(struct vm_area_struct * area, unsigned long address, int unused); }; vm_operations结构中包含的是函数指针;其中,open、 vm_operations结构中包含的是函数指针;其中,open、close 结构中包含的是函数指针 分别用于虚存区的打开、关闭, nopage是当虚存页面不在物 分别用于虚存区的打开、关闭,而nopage是当虚存页面不在物 理内存而引起的“缺页异常”时所应该调用的函数。 理内存而引起的“缺页异常”时所应该调用的函数。
网络工程系 曾令明
内核空间到物理内存的映射
虚拟地址空间 4G
3G
物理内存 X 0 0
图4.1 内核的虚拟地址空间到物理地址空间的映射
网络工程系 曾令明
虚拟内存实现机制
• Linux虚拟内存的实现需要多种机制的支持 虚拟内存的实现需要多种机制的支持
• 地址映射机制 • 请页机制 • 内存分配和回收机制 • 交换机制 • 缓存和刷新机制
VM_AREA_STRUCT 结构
Vm_mm Vm_start, , vm_end
指向虚存区所在的mm_struct结构的指针。 指向虚存区所在的mm_struct结构的指针。 mm_struct结构的指针 虚存区的起始地址和终止地址。 虚存区的起始地址和终止地址。
Vm_page_prot 虚存区的保护权限。 虚存区的保护权限。 Vm_flags Vm_next 虚存区的标志。 虚存区的标志。 构成线性链表的指针,按虚存区基址从小到大排列。 构成线性链表的指针,按虚存区基址从小到大排列。
内存管理
• Linux的内存管理 的内存管理 • 进程的用户空间管理 • 请页机制 • 物理内存的分配与回收 • 交换机制 • 内存管理示例
网络工程系 曾令明
网络工程系 曾令明
扩大了的记忆—虚拟内存 扩大了的记忆 虚拟内存
• 虚拟内存的基本思想:在计算机中运行的程 虚拟内存的基本思想: 基本思想 其代码、 序,其代码、数据和堆栈的总量可以超过实 际内存的大小, 际内存的大小,操作系统只将当前使用的程 序块保留在内存中, 序块保留在内存中,其余的程序块则保留在 磁盘上。必要时, 磁盘上。必要时,操作系统负责在磁盘和内 存之间交换程序块。 存之间交换程序块。
网络工程系 曾令明
mm_struct 结构
struct mm_struct { count; atomic_t count; pgd_t * pgd; pgd; map_count; int map_count; mmap_sem; struct semaphore mmap_sem; start_code,end_code,start_data,end_data; unsigned long start_code,end_code,start_data,end_data; start_stack; unsigned long start_brk, brk, start_stack; unsigned long arg_start, arg_end, env_start, env_end; env_end; locked_vm; unsigned long rss, total_vm, locked_vm; def_flags; unsigned long def_flags; *mmap_cache; struct vm_area_struct *mmap, *mmap_avl, *mmap_cache; swap_cnt; unsigned long swap_cnt; unsigned long swap_address; swap_address; }; 网络工程系 曾令明
网络工程系 曾令明
相关数据结构间的关系
• 进程控制块是内核中的核心数据结构。 进程控制块是内核中的核心数据结构。 • 在进程的 task_struct 结构中包含一个 mm域,它是指向 mm_struct 结构的指针。 结构的指针。 域 • 而进程的 mm_struct结构则包含进程的可 结构则包含进程的可 执行映像信息以及进程的页目录指针pgd等。 执行映像信息以及进程的页目录指针 等 • 该结构还包含有指向 vm_area_struct 结 构的几个指针, 构的几个指针,每个 vm_area_struct 代 表进程的一个虚拟地址区间。 表进程的一个虚拟地址区间。
pgd
map_count semaphore Start_code,end_code, start_data, end_data
start_brk, brk, start_stack; 网络工程系 曾令明
每个进程都有一个特殊的地址区间, 每个进程都有一个特殊的地址区间,这个区间就是所 谓的堆,也就是前面图中的空洞。 前面图中的空洞 谓的堆,也就是前面图中的空洞。前两个域分别描述 堆的起始地址和终止的地址, 堆的起始地址和终止的地址,最后一个域描述堆栈段 的起始地址。 的起始地址。
网络工程系 曾令明
进程用户空间
• Linux把进程的用户空间划分为一个个区间 虚拟 把进程的用户空间划分为一个个区间(虚拟 把进程的用户空间划分为一个个区间 区),便于管理 • 一个进程的用户地址空间主要由 一个进程的用户地址空间主要由mm_struct结构 结构 结构来描述。 和vm_area_structs结构来描述。 结构来描述 • mm_struct结构它对进程整个用户空间进行描述 结构它对进程整个用户空间进行描述 • vm_area_structs结构对用户空间中各个区间 结构对用户空间中各个区间 (简称虚存区 进行描述 简称虚存区)进行描述 简称虚存区 • vm_operation结构描述了在这些区上的操作 结构描述了在这些区上的操作
mmap_avl mmap_cache
网络工程系 曾令明
struct vm_area_struct { vm_mm; struct mm_struct * vm_mm; unsigned long vm_start; vm_start; vm_end; unsigned long vm_end; vm_page_prot; pgprot_t vm_page_prot; vm_flags; unsigned short vm_flags; *vm_next; struct vm_area_struct *vm_next; short vm_avl_height; vm_avl_height; *vm_avl_right; struct vm_area_struct *vm_avl_left, *vm_avl_right; vm_ops; struct vm_operations_struct * vm_ops; **vm_pprev_share; struct vm_area_struct *vm_next_share, **vm_pprev_share; vm_offset; unsigned long vm_offset; struct file * vm_file; vm_file; vm_pte; unsigned long vm_pte; }; 网络工程系 曾令明