第四章 内存管理.ppt

上传人:syndromehi216 文档编号:374201 上传时间:2018-10-05 格式:PPT 页数:54 大小:968KB
下载 相关 举报
第四章 内存管理.ppt_第1页
第1页 / 共54页
第四章 内存管理.ppt_第2页
第2页 / 共54页
第四章 内存管理.ppt_第3页
第3页 / 共54页
第四章 内存管理.ppt_第4页
第4页 / 共54页
第四章 内存管理.ppt_第5页
第5页 / 共54页
亲,该文档总共54页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

1、第四章 内存管理,Linux的内存管理,进程的用户空间管理,请页机制,物理内存的分配与回收,交换机制,内存管理示例,内存的层次结构,虚拟内存的基本思想:在计算机中运行的程序,其代码、数据和堆栈的总量可以超过实际内存的大小,操作系统只将当前使用的程序块保留在内存中,其余的程序块则保留在磁盘上。必要时,操作系统负责在磁盘和内存之间交换程序块。,扩大了的记忆虚拟内存,虚地址到实地址转换,虚拟内存、内核空间和用户空间,内核空间(1GB),进程1的用户空间(3GB),进程2的用户空间(3GB),进程n的用户空间(3GB),虚拟地址空 间,虚拟内存共4G字节,分为内核空间(最高的1G字节)和用户空间(较低

2、的3G字节)两部分,每个进程最大拥有3G字节私有虚存空间 地址转换通过页表把虚存空间的一个地址转换为物理空间中的实际地址。,虚拟内存、内核空间和用户空间,内核空间由所有进程共享,其中存放的是内核代码和数据,即“内核映象” 进程的用户空间中存放的是用户程序的代码和数据 内核空间映射到物理内存总是从最低地址(0x00000000)开始,使之在内核空间与物理内存之间建立简单的线性映射关系。,内核空间到物理内存的映射,0,3G,4G,0,X,虚拟地址空间,物理内存,图4.1 内核的虚拟地址空间到物理地址空间的映射,内核空间到物理内存的映射,Linux虚拟内存的实现需要多种机制的支持 地址映射机制 请页

3、机制 内存分配和回收机制 交换机制 缓存和刷新机制,虚拟内存实现机制,地址映射,图4.2 虚拟内存实现机制及之间的关系,虚拟内存实现机制及之间的关系,每个进程经编译、链接后形成的二进制映像文件有一个代码段和数据段 进程运行时须有独占的堆栈空间,进程的用户空间管理,堆栈段,空洞,数据段,代码段,进程的用户空间(3G),Linux把进程的用户空间划分为一个个区间,便于管理 一个进程的用户地址空间主要由mm_struct结构和vm_area_structs结构来描述。 mm_struct结构它对进程整个用户空间进行描述 vm_area_structs结构对用户空间中各个区间(简称虚存区)进行描述,进

4、程用户空间,struct mm_struct atomic_t count;pgd_t * pgd;int map_count; struct semaphore mmap_sem; unsigned long start_code,end_code,start_data,end_data; unsigned long start_brk, brk, start_stack; unsigned long arg_start, arg_end, env_start, env_end; unsigned long rss, total_vm, locked_vm; unsigned long de

5、f_flags; struct vm_area_struct *mmap, *mmap_avl, *mmap_cache;unsigned long swap_cnt; unsigned long swap_address; ;,mm_struct 结构,struct vm_area_struct struct mm_struct * vm_mm; unsigned long vm_start; unsigned long vm_end; pgprot_t vm_page_prot; unsigned short vm_flags; struct vm_area_struct *vm_next

6、;short vm_avl_height; struct vm_area_struct *vm_avl_left, *vm_avl_right; struct vm_operations_struct * vm_ops;struct vm_area_struct *vm_next_share, *vm_pprev_share; unsigned long vm_offset; struct file * vm_file; unsigned long vm_pte; ;,VM_AREA_STRUCT 结构,进程控制块是内核中的核心数据结构。 在进程的 task_struct 结构中包含一个mm域

7、,它是指向 mm_struct 结构的指针。 而进程的 mm_struct结构则包含进程的可执行映像信息以及进程的页目录指针pgd等。 该结构还包含有指向 vm_area_struct 结构的几个指针,每个 vm_area_struct 代表进程的一个虚拟地址区间。,相关数据结构间的关系,相关数据结构之间的关系示意图,fork()系统调用在创建新进程时也为该进程创建完整的用户空间 具体而言,是通过拷贝或共享父进程的用户空间来实现的,即内核调用copy_mm( )函数,为新进程建立所有页表和mm_struct结构Linux利用“写时复制”技术来快速创建进程,创建进程用户空间,执行一个进程时,其可

8、执行映像必须装入进程的用户地址空间 虚存映射:即把文件从磁盘映射到进程的用户空间,对文件的访问转化为对虚存区的访问 有共享的、私有的虚存映射和匿名映射 当可执行映像映射到进程的用户空间时,将产生一组 vm_area_struct 结构来描述各虚拟区间的起始点和终止点,虚存映射,例:exam.c int main() printf(“virtual area test!”); ,进程的虚存区举例,exam进程的虚存区,与用户空间相关的主要系统调用,进程运行时,CPU访问的是用户空间的虚地址 Linux仅把当前要使用的少量页面装入内存,需要时再通过请页机制将特定的页面调入内存 当要访问的虚页不在内

9、存时,产生一个页故障并报告故障原因,请页机制实现虚存管理的重要手段,缺页异常处理程序,否,是,是,是,否,否,总体方案,缺页异常处理流程图,否,否,否,否,否,否,否,否,否,是,是,是,是,是,是,是,是,是,请求调页:把页面的分配推迟到进程要访问的页不在物理内存时为止,由此引起一个缺页异常 引入原因:进程开始运行时并不访问其地址空间中的全部地址 程序的局部性原理保证请求调页从总体上使系统有更大的吞吐量。,请求调页动态内存分配技术,写时复制技术可以推迟、甚至免除数据的拷贝 进程创建之初内核并不复制整个进程空间,而是使父子进程以只读方式共享同一个拷贝 数据只有在需要写入时才会被复制,从而使各个

10、进程拥有各自的拷贝,写时复制(copyonwrite)技术,在Linux中,CPU所访问的地址是虚拟地址空间的虚地址; 管理内存页面时,先在虚存空间中分配一个虚存区间,然后才根据需要为此区间分配相应的物理页面并建立起映射 Linux采用著名的伙伴(Buddy)算法来解决外碎片问题,物理内存的分配与回收,Linux的伙伴算法把所有的空闲页面分为10个块链表,每个链表中的一个块含有2的幂次个页面(叫做“页块”或简称“块” ) 大小相同、物理地址连续的两个页块被称为“伙伴” 工作原理:首先在大小满足要求的块链表中查找是否有空闲块,若有则直接分配,否则在更大的块中查找。其逆过程就是块的释放,此时会把满

11、足伙伴关系的块合并,页面分配与回收算法伙伴算法,函数_get_free_pages 用于分配物理页块 该函数所做的工作如下: 检查所请求的页块大小是否能够被满足 检查系统中空闲物理页的总数是否已低于允许的下界 正常分配。从free_area数组的第order项开始,这是一个mem_map_t链表。 换页。通过下列语句调用函数try_to_free_pages(),启动换页进程,物理页面的分配,1) 如果该链表中有满足要求的页块,则:将其从链表中摘下;将free_area数组的位图中该页块所对应的位取反,表示页块已用;修改全局变量nr_free_pages(减去分配出去的页数);根据该页块在me

12、m_map数组中的位置,算出其起始物理地址,返回。 2) 如果该链表中没有满足要求的页块,则在free_area数组中顺序向上查找。其结果有二:a) 整个free_area数组中都没有满足要求的页块,此次无法分配,返回。b) 找到一个满足要求的页块,则:将其从链表中摘下; 将free_area数组的位图中该页块所对应的位取反,表示页块已用;修改全局变量nr_free_pages(减去分配出去的页数);因为页块比申请的页块要大,所以要将它分成适当大小的块。因为所有的页块都由2的幂次的页数组成,所以这个分割的过程比较简单,只需要将它平分就可以:I. 将其平分为两个伙伴,将小伙伴加入free_are

13、a数组中相应的链表,修改位图中相应的位;II.如果大伙伴仍比申请的页块大,则转I,继续划分;III.大伙伴的大小正是所要的大小,修改位图中相应的位,根据其在mem_map数组中的位置,算出它的起始物理地址,返回。,函数free_pages用于页块的回收 该函数所做的工作如下: 根据页块的首地址addr算出该页块的第一页在mem_map数组的索引; 如果该页是保留的(内核在使用),则不允许回收; 将页块第一页对应的mem_map_t结构中的count域减1,表示引用该页的进程数减了1个。若count域的值不为0,有别的进程在使用该页块,不能回收,仅简单返回 清除页块第一页对应的mem_map_t

14、结构中flags域的PG_referenced位,表示该页块不再被引用; 将全局变量nr_free_pages的值加上回收的物理页数 将页块加入到数组free_area的相应链表中,物理页面的回收,Slab机制提出的原因: 为了减少对伙伴算法的调用次数 内核经常反复使用某一内存区 内存区可根据其使用频率来分类 硬件高速缓存的使用,为尽量减少对伙伴算法的调用提供了另一个理由,Slab 分配机制分配小内存,Slab分配模式把对象分组放进缓冲区 Slab缓冲区由一连串的“大块(Slab)”构成,每个大块中包含若干个同种类型的对象,这些对象或已被分配,或空闲 简言之,缓冲区就是主存中的一片区域,把这片

15、区域划分为多个块,每块就是一个Slab,每个Slab由一个或多个页面组成,每个Slab中存放的就是对象,Slab 分配机制分配小内存,Slab 的组成,专用缓冲区主要用于频繁使用的数据结构 缓冲区是用kmem_cache_t类型描述的,通过kmem_cache_create()来建立 函数kmem_cache_create()所创建的缓冲区中还没有包含任何Slab,因此,也没有空闲的对象。只有以下两个条件都为真时,才给缓冲区分配Slab: 已发出一个分配新对象的请求; 缓冲区不包含任何空闲对象;,Slab专用缓冲区的建立和释放,创建缓冲区后,可通过函数kmem_cache_alloc()从中获

16、取对象 该函数从给定的缓冲区中返回一个指向对象的指针。如果缓冲区中所有的slab中都没有空闲的对象,则 slab必须调用_get_free_pages()获取新的页面 使用函数kmem_cache_free()可以释放一个对象,并把它返回给原先的slab,Slab专用缓冲区的建立和释放,在内核中初始化开销不大的数据结构可以合用一个通用的缓冲区。 通用缓冲区类似于物理页面分配中的大小分区 对通用缓冲区的管理采用Slab方式 当一个数据结构的使用不频繁、或其大小不足一个页面时,没有必要给其分配专用缓冲区 ,可调用函数kmallo() 分配通用缓冲区,通用缓冲区,非连续内存处于3G到4G之间的内核空

17、间PAGE_OFFSET为3GB,high_memory为保存物理地址最高值的变量,VMALLOC_START为非连续区的起始地址,内核空间非连续内存区的分配,high_memory,从PAGE_OFFSET开始的内核地址区间,vmalloc()与 kmalloc()都可用于分配内存 kmalloc()分配的内存处于3GBhigh_memory之间,这段内核空间与物理内存的映射一一对应,而vmalloc()分配的内存在VMALLOC_START4GB之间,这段非连续内存区映射到物理内存也可能是非连续的 vmalloc() 分配的物理地址无需连续,而kmalloc() 确保页在物理上是连续的,v

18、malloc()与 kmalloc()之区别,当物理内存不足时,Linux通过某种机制选出内存中的某些页面换到磁盘上,以便留出空闲区来调入需要使用的页面 交换的基本原理:当空闲内存数量小于一个固定的极限值时,就执行换出操作(包括把进程的整个地址空间拷贝到磁盘上)。反之,当调度算法选择一个进程运行时,整个进程又被从磁盘中交换进来,交换机制,在Linux中,进行交换的单位是页面而不是进程 在页面交换中,页面置换算法是影响交换性能的关键性指标,其复杂性主要与换出有关 : 哪种页面要换出 如何在交换区中存放页面 如何选择被交换出的页面,页面交换,只有与用户空间建立了映射关系的物理页面才会被换出,内核空

19、间中内核所占的页面则常驻内存 进程映像所占的页面 ,其代码段、数据段可被换入换出,但堆栈段一般不换出 通过系统调用mmap()把文件内容映射到用户空间时,页面所使用的交换区就是被映射的文件本身 进程间共享内存区其页面的换入换出比较复杂 映射到内核空间中的页面都不会被换出 内核在执行过程中使用的页面要经过动态分配,但永驻内存,选择被换出的页面,交换区也被划分为块,每个块的大小恰好等于一页,一块叫做一个页插槽 换出时,内核尽可能把换出的页放在相邻的插槽中,从而减少访问交换区时磁盘的寻道时间 若系统使用了多个交换区,快速交换区可以获得比较高的优先级 当查找一个空闲插槽时,要从优先级最高的交换区中开始

20、搜索 如果优先级最高的交换区不止一个,应该循环选择相同优先级的交换区,在交换区中存放页面,策略1:需要时才交换 策略2:系统空闲时交换 策略3:换出但并不立即释放 策略4:把页面换出推迟到不能再推迟为止 页面换入换出及回收的基本思想,页面交换策略,释放页面。如果一个页面变为空闲可用,就把该页面的page结构链入某个空闲队列free_area,同时页面的使用计数count减1。 分配页面。调用_get_free_page()从某个空闲队列分配内存页面,并将其页面的使用计数count置为1。 活跃状态。已分配的页面处于活跃状态,该页面的数据结构page通过其队列头结构lru链入活跃页面队列acti

21、ve_list,并且在进程地址空间中至少有一个页与该页面之间建立了映射关系。 不活跃“脏”状态。处于该状态的页面其page结构通过其队列头结构lru链入不活跃“脏”页面队列inactive_dirty_list,并且原则是任何进程的页面表项不再指向该页面,也就是说,断开页面的映射,同时把页面的使用计数count减1。 将不活跃“脏”页面的内容写入交换区,并将该页面的page结构从不活跃“脏”页面队列inactive_dirty_list转移到不活跃“干净”页面队列,准备被回收。 不活跃“干净”状态。页面page结构通过其队列头结构lru链入某个不活跃“干净”页面队列。 如果在转入不活跃状态以后

22、的一段时间内,页面又受到访问,则又转入活跃状态并恢复映射。 当需要时,就从“干净”页面队列中回收页面,也就是说或者把页面链入到空闲队列,或者直接进行分配。,Linux内核利用守护进程kswapd定期地检查系统内的空闲页面数是否小于预定义的极限,一旦发现空闲页面数太少,就预先将若干页面换出 kswapd相当于一个进程,它有自己的进程控制块task_struct结构,与其它进程一样受内核调度,但没有独立的地址空间,页面交换守护进程kswapd,希望通过访问用户空间的内存达到读取内核数据的目的,这样便可进行内核空间到用户空间的大规模信息传送,从而应用于高速数据采集等性能要求高的场合 从用户空间直接读

23、取内核数据 ,即利用内存映射功能,将内核中的一部分虚拟内存映射到用户空间,使得访问用户空间地址等同于访问被映射的内核空间地址,从而不再需要数据拷贝操作,内存管理实例,在内核空间中调用kmalloc()分配连续物理空间,而调用vmalloc()分配非物理连续空间。 我们把kmalloc()所分配内核空间中的地址称为内核逻辑地址 把vmalloc()分配的内核空间中的地址称为内核虚拟地址 vmalloc()在分配过程中须更新内核页表,相关背景知识,跨空间的地址映射主要包括 : 找到内核地址对应的物理地址,这是为了将用户页表项直接指向物理地址;建立新的用户页表项,代码体系结构介绍,用户虚存区映射到V

24、K对应的物理内存,任务的执行路径,编译map_driver.c为map_driver.o模块,具体参数见Makefile 加载模块 :insmod map_driver.o 生成对应的设备文件 在/proc/devices下找到map_driver对应的设备命和设备号:grep mapdrv /proc/devices 建立设备文件mknod mapfile c 254 0 利用maptest读取mapfile文件,将取自内核的信息(”ok”我们在内核中在vmalloc分配的空间中填放的信息)打印到用户屏幕。,STEP BY STEP,“内核之旅 ”网站,http:/ 电子杂志栏目是关于内核研究和学习的资料 第五期“Linux内存管理”,从应用程序开发者的角度审视Linux的进程内存管理,在此基础上逐步深入到内核中讨论系统物理内存管理和内核内存的使用方法。力求从外到内、水到渠成地引导网友分析Linux的内存管理与使用。 下载实例代码进行调试,

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 教学课件 > 大学教育

copyright@ 2008-2019 麦多课文库(www.mydoc123.com)网站版权所有
备案/许可证编号:苏ICP备17064731号-1