您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 项目/工程管理 > linux内核-第四章 内存管理
第四章内存管理Linux的内存管理进程的用户空间管理请页机制物理内存的分配与回收交换机制内存管理示例内存的层次结构虚拟内存的基本思想:在计算机中运行的程序,其代码、数据和堆栈的总量可以超过实际内存的大小,操作系统只将当前使用的程序块保留在内存中,其余的程序块则保留在磁盘上。必要时,操作系统负责在磁盘和内存之间交换程序块。扩大了的记忆-虚拟内存虚地址到实地址转换虚拟地址虚拟内存、内核空间和用户空间内核空间(1GB)进程1的用户空间(3GB)进程2的用户空间(3GB)进程n的用户空间(3GB)虚拟地址空间虚拟内存-共4G字节,分为内核空间(最高的1G字节)和用户空间(较低的3G字节)两部分,每个进程最大拥有3G字节私有虚存空间地址转换-通过页表把虚存空间的一个地址转换为物理空间中的实际地址。虚拟内存、内核空间和用户空间内核空间由所有进程共享,其中存放的是内核代码和数据,即“内核映象”进程的用户空间中存放的是用户程序的代码和数据内核空间映射到物理内存总是从最低地址(0x00000000)开始,使之在内核空间与物理内存之间建立简单的线性映射关系。内核空间到物理内存的映射03G4G0X虚拟地址空间物理内存图4.1内核的虚拟地址空间到物理地址空间的映射内核空间到物理内存的映射•Linux虚拟内存的实现需要多种机制的支持–地址映射机制–请页机制–内存分配和回收机制–交换机制–缓存和刷新机制虚拟内存实现机制地址映射图4.2虚拟内存实现机制及之间的关系虚拟内存实现机制及之间的关系•每个进程经编译、链接后形成的二进制映像文件有一个代码段和数据段•进程运行时须有独占的堆栈空间进程的用户空间管理堆栈段空洞数据段代码段进程的用户空间(3G)•Linux把进程的用户空间划分为一个个区间,便于管理•一个进程的用户地址空间主要由mm_struct结构和vm_area_structs结构来描述。•mm_struct结构它对进程整个用户空间进行描述•vm_area_structs结构对用户空间中各个区间(简称虚存区)进行描述进程用户空间structmm_struct{atomic_tcount;pgd_t*pgd;intmap_count;structsemaphoremmap_sem;unsignedlongstart_code,end_code,start_data,end_data;unsignedlongstart_brk,brk,start_stack;unsignedlongarg_start,arg_end,env_start,env_end;unsignedlongrss,total_vm,locked_vm;unsignedlongdef_flags;structvm_area_struct*mmap,*mmap_avl,*mmap_cache;unsignedlongswap_cnt;unsignedlongswap_address;};mm_struct结构域名说明count对mm_struct结构的引用进行计数。为了在Linux中实现线程,内核调用clone派生一个线程,线程和调用进程共享用户空间,即mm_struct结构,派生后系统会累加mm_struct中的引用计数。pgd进程的页目录基地址,当调度程序调度一个进程运行时,就将这个地址转成物理地址,并写入控制寄存器(CR3)map_count在进程的整个用户空间中虚存区的个数semaphore对mm_struct结构进行串行访问所使用的信号量Start_code,end_code,start_data,end_data进程的代码段和数据段的起始地址和终止地址start_brk,brk,start_stack;每个进程都有一个特殊的地址区间,这个区间就是所谓的堆,也就是图4.4中的空洞。前两个域分别描述堆的起始地址和终止的地址,最后一个域描述堆栈段的起始地址。arg_start,arg_end,env_start,env_end命令行参数所在的堆栈部分的起始地址和终止地址;环境串所在的堆栈部分的起始地址和终止地址rss,total_vm,locked_vm进程贮留在物理内存中的页面数,进程所需的总页数,被锁定在物理内存中的页数。mmapvm_area_struct虚存区结构形成一个单链表,其基址由小到大排列mmap_avlvm_area_struct虚存区结构形成一个颗AVL平衡树mmap_cache最近一次用到的虚存区很可能下一次还要用到,因此,把最近用到的虚存区结构放入高速缓存,这个虚存区就由mmap_cache指向。structvm_area_struct{structmm_struct*vm_mm;unsignedlongvm_start;unsignedlongvm_end;pgprot_tvm_page_prot;unsignedshortvm_flags;structvm_area_struct*vm_next;shortvm_avl_height;structvm_area_struct*vm_avl_left,*vm_avl_right;structvm_operations_struct*vm_ops;structvm_area_struct*vm_next_share,**vm_pprev_share;unsignedlongvm_offset;structfile*vm_file;unsignedlongvm_pte;};VM_AREA_STRUCT结构域名说明Vm_mm指向虚存区所在的mm_struct结构的指针。Vm_start,vm_end虚存区的起始地址和终止地址。Vm_page_prot虚存区的保护权限。Vm_flags虚存区的标志。Vm_next构成线性链表的指针,按虚存区基址从小到大排列。vm_avl_height,vm_avl_left,vm_avl_right这3个域在一起构成AVL树,其中vm_avl_height是该节点距根节点的高度,vm_avl_left和vm_avl_right分别是该节点的左右两个子树。Vm_ops对虚存区进行操作的函数。这些给出了可以对虚存区中的页所进行的操作。•进程控制块是内核中的核心数据结构。•在进程的task_struct结构中包含一个mm域,它是指向mm_struct结构的指针。•而进程的mm_struct结构则包含进程的可执行映像信息以及进程的页目录指针pgd等。•该结构还包含有指向vm_area_struct结构的几个指针,每个vm_area_struct代表进程的一个虚拟地址区间。相关数据结构间的关系相关数据结构之间的关系示意图•fork()系统调用在创建新进程时也为该进程创建完整的用户空间•具体而言,是通过拷贝或共享父进程的用户空间来实现的,即内核调用copy_mm()函数,为新进程建立所有页表和mm_struct结构•Linux利用“写时复制”技术来快速创建进程创建进程用户空间•执行一个进程时,其可执行映像必须装入进程的用户地址空间•虚存映射:即把文件从磁盘映射到进程的用户空间,对文件的访问转化为对虚存区的访问•有共享的、私有的虚存映射和匿名映射•当可执行映像映射到进程的用户空间时,将产生一组vm_area_struct结构来描述各虚拟区间的起始点和终止点虚存映射例:exam.cintmain(){printf(“virtualareatest!”);}进程的虚存区举例地址范围许可权偏移量所映射的文件08048000-08049000r-xp00000000/home/test/exam08049000-0804a000rw-p00001000/home/test/exam40000000-40015000r-xp00000000/lib/ld-2.3.2.so40015000-40016000rw-p00015000/lib/ld-2.3.2.so40016000-40017000rw-p00000000匿名4002a000-40159000r-xp00000000/lib/libc-2.3.2.so40159000-4015e000rw-p0012f000/lib/libc-2.3.2.so4015e000-40160000rw-p00000000匿名bfffe000-c0000000rwxpfffff000匿名exam进程的虚存区与用户空间相关的主要系统调用系统调用描述fork()创建具有新的用户空间的进程,用户空间中的所有页被标记为“写时复制”,且由父子进程共享,当其中的一个进程所访问的页不在内存时,这个页就被复制一份。mmap()在进程的用户空间内创建一个新的虚存区。munmap()销毁一个完整的虚存区或其中的一部分,如果要取消的虚存区位于某个虚存区的中间,则这个虚存区被划分为两个虚存区。exec()装入新的可执行文件以代替当前用户空间。Exit()销毁进程的用户空间及其所有的虚存区。•进程运行时,CPU访问的是用户空间的虚地址•Linux仅把当前要使用的少量页面装入内存,需要时再通过请页机制将特定的页面调入内存•当要访问的虚页不在内存时,产生一个页故障并报告故障原因请页机制-实现虚存管理的重要手段缺页异常处理程序这个虚地址属于进程的用户空间?访问类型与这个虚存区的访问权匹配?异常发生在用户态?合法访问:分配一个新的页面非法访问:发送一个SIGSEBV信号内核错误:杀死进程否是是是否否总体方案地址在中断中或内核线程中地址在虚存区中写访问区是可写的写时复制地址可能属于用户态栈页存在区是可读或可执行的在用户态地址是一个错误的系统调用参数请求调页发送SIGSEGV信号杀死进程通常情况下发送SIGSEGV信号缺页异常处理流程图否否否否否否否否否是是是是是是是是是•请求调页:把页面的分配推迟到进程要访问的页不在物理内存时为止,由此引起一个缺页异常•引入原因:进程开始运行时并不访问其地址空间中的全部地址•程序的局部性原理保证请求调页从总体上使系统有更大的吞吐量。请求调页-动态内存分配技术•写时复制技术可以推迟、甚至免除数据的拷贝•进程创建之初内核并不复制整个进程空间,而是使父子进程以只读方式共享同一个拷贝•数据只有在需要写入时才会被复制,从而使各个进程拥有各自的拷贝写时复制(copy-on-write)技术•在Linux中,CPU所访问的地址是虚拟地址空间的虚地址;•管理内存页面时,先在虚存空间中分配一个虚存区间,然后才根据需要为此区间分配相应的物理页面并建立起映射•Linux采用著名的伙伴(Buddy)算法来解决外碎片问题物理内存的分配与回收保留内核映象动态内存00x100000start_memend_mem•Linux的伙伴算法把所有的空闲页面分为10个块链表,每个链表中的一个块含有2的幂次个页面(叫做“页块”或简称“块”)•大小相同、物理地址连续的两个页块被称为“伙伴”•工作原理:首先在大小满足要求的块链表中查找是否有空闲块,若有则直接分配,否则在更大的块中查找。其逆过程就是块的释放,此时会把满足伙伴关系的块合并页面分配与回收算法-伙伴算法•函数__get_free_pages用于分配物理页块•该函数所做的工作如下:–检查所请求的页块大小是否能够被满足–检查系统中空闲物理页的总数是否已低于允许的下界–正常分配。从free_area数组的第order项开始,这是一个mem_map_t链表。–换页。通过下列语句调用函数try_to_free_pages(),启动换页进程物理页面的分配•1)如果该链表中有满足要求的页块,则:•将其从链表中摘下;将free_area数组的位图中该页块所对应的位取反,表示页块已用;修改全局变量nr_free_pages(减去分配出去的页数);根据该页块在mem_map数组中的位置,算出其起始物理地址,返回。•2)如果该链表中没有满足要求的页块,则在fr
本文标题:linux内核-第四章 内存管理
链接地址:https://www.777doc.com/doc-3392059 .html