随记:为了对内存的存储单元进行识别,内存的每一个存储单元都必须有一个确定的地址,而一台计算机的处理器能访问多大的内存空间取决于处理器的程序计数器,该计数器的字长越长,能访问的空间就越大、
目录
传统计算机虚拟内存技术
寻址空间/寻址能力:对于程序计数器位32位的处理器来说,它的地址发生器所能发出的寻址数量为二的32次 = 4G ,于是这个处理器所能访问的最大内存空间就是4G。在计算机技术中,这个值就叫做处理器的寻址空间或寻址能力
一般来说,为了充分利用处理器的寻址能力,就应该按照处理器的最大寻址来为其分配系统的内存,这样处理器发出的每一个地址就都会有一个正式的物理村塾单元与之对应,同时每一个物理存储单元都有唯一的地址与之对应
但实际上计算机所配置的内存的实际空间常常小于处理器的寻址范围,这样就会照成处理器的寻址能力的浪费
实验证明:一个应用程序总是逐段被运行的,而且在一段时间内会稳定运行在某一段程序里面
解决内存不够的方法:把要运行的那一段程序从辅存复制到内存中来运行,而其他展示不运行的程序段就让他仍然留在辅存
在计算机中换入,换出,虚拟内存,物理内存定义
在计算机中,把从内存中的程序段复制回辅存的做法叫做 换出 ,而把从辅存中的程序段映射到内存的做法叫做 换入 , 经过不断有目的的换出和换入没处理器就可以运行一个大于实际物理空间的应用程序了,或者说处理器似乎拥有了一个大于实际物理内存的内存空间,于是这个存储空间叫做虚拟内存空间,而把真正的内存空间叫做实际物理内存,简称为物理内存
对于一台真实计算机来说,它的虚拟内存空间的大小是由程序计数器的寻址能力来决定的
如果一个系统采用了虚拟内存空间技术,那么它就存在着两个内存空间:虚拟内存空间,物理内存空间
虚拟内存空间中的地址叫做虚拟地址。而实际物理内存空间中的地址叫做实际物理地址或物理地址
处理器运算器和应用程序设计人员看到的只是虚拟内存空间和虚拟地址,而处理器片外的地址总线看到的只是物理地址空间和物理地址
由于存在两个内存地址,因此一个应用程序从编写到被执行,需要进行两次映射:第一次是映射到虚拟内存空间,第二次是映射到物理内存空间。在计算机系统中这两次映射的工作是由硬件和软件共同来完成的。承担这个任务的硬件部分叫做内存管理单元(MMU),软件部分就是操作系统的内存管理模块
在映射工作中,为了记录程序段占用物理空间的情况,操作系统的内存管理模块需要建立一个表格,该表格以虚拟地址为索引,记录了程序段所占用的物理内存的物理地址,这个虚拟地址/物理地址记录表就是内存管理单元把虚拟地址转换为物理地址的依据
综上所述虚拟内存技术的实现,是建立在应用程序可以被分成段
并且具有在任何时候正在使用的信息总是所有存储信息的一小部分的局部特性的基础上的
它是通过辅存空间(RAM)来实现的一种是机器的作业地址大于实际内存的技术
从处理运算装置和程序设计人员的角度来看,它面对的是一个用MMU,映射记录表和物理内存分装起来的一个虚拟内存空间,这个存储空间的大小取决于处理器程序计数器的寻址空间
Linux的虚拟内存技术
以存储单元为单位来管理显然是不现实的。因此Linux把虚拟内存空间分为若干个大小相同的存储空间,Linux把这样的分区叫做页,为了换入和换出的发个遍,物理内存也就按页的大小分为若干块。由于物理内存中的块空间是用来容纳虚拟内存的页的容器,所以物理内存的块叫做页框,页和页框是Linux实现虚拟内存技术的基础
虚拟内存的页,物理内存的页框及页表
在Linux中页与页框的大小一般为4kb,当然,根据系统的不同,页和页框的大小也有可能有所改变
物理地址和虚拟地址被分为了页框和页后,其存储单元原来的地址都自然的被分为看i昂段没并且这两段各自代表着不同的意义:高位段分别叫做页框码和页码,他们是识别页框和页码的编码,低位段分别叫做页框偏移量和页内偏移量,他们是存储单元在页框和页内的地址编码
为了使系统能正确的访问虚拟内存页在对应页框中的映像,在把一个页映射到页框的时候,就必须把页码和存放该页映像的页框码填入一个叫做页表的表项中(**这是关键**)
处理器遇到的地址都是虚拟地址,秀妮地址和物理地址都分为页码(页框码)和偏移值两部分,在由虚拟地址转换成物理地址的过程中,偏移值不变,而页码和页框码之间的映射就在一个映射记录表中-----页表中
请页与交换
页面的加载:虚拟页面到物理页框的映射叫做页面的加载
请页机制:
当处理器访问一个虚拟内存时,首先到页表中去查询该页是否已经映射到物理页框中,并记录在页表中,如果在,则MMU回把页码转换为页框码,并加上虚拟地址提供的页内偏移量形成物理地址否访问物理内存,如果不在则意味着该虚拟页面还没被加载入内存,这是MMU就会通知操作系统:发生了一个页面访问错误(页面错误),接下来系统会启动所谓的请页机制,及调用相应的系统操作函数,判断该虚拟地址是否为有效地址
如果是有效的地址,就会从虚拟内存中将该地址指向的页面读入到内存的一个空闲页框中,并在页表加上项对应的表项,最后处理器将从发生页面错误的地方从星开始运行,如果是无效的地址,则表明进程在试图访问一个不存在的虚拟地址,此时操作系统将终止此次访问
衰老算法:
为了公平的选择从系统中将要抛弃的页面:Linux使用(LRU)页面的衰老算法。这种策略根据系统中每个页面被访问的频率,为物理页框中的页面设置了一个叫做年龄的属性,页面被访问的次数越多,则页面的年龄就越小;相反,页面被访问的次数越少,则年龄越大,而年龄越大的页面就是待换出页面的最佳获选者
快表:
在系统每次访问虚存页时,都要在内存的所有页表中寻找该页的页框,这是一个很费时间的工作。但是,人们发现,系统一旦访问了某一个页,那么系统就会在一段时间内稳定地工作在这个页上。所以,为了提高访问页表的速度,系统还配备了一组正好能容纳一个页表的硬件寄存器,这样当系统再访问虚存时,就首先到这组硬件寄存器中去访问,系统速度就快多了。这组存放当前页表的寄存器叫做快
Linux的页表结构:
Linux一共有三级页表
为了通用,Linux系统使用了三级页表结构:页目录、中间页目录和页表。PGD为顶级页表,是一个pgd_t数据类型(定义在文件linux/include/page.h中)的数组,每个数组元素指向一个中间页目录;PMD为二级页表,是一个pmd_t数据结构的数组,每个数组元素指向一个页表;PTE则是页表,是一个pte_t数据类型的数组,每个元素中含有物理地址。
在系统编译时,会根据配置文件config中的配置,把目录include/asm符号连接到具体CPU专用的文件目录中。例如,对于i386CPU,该目录符号会连接到include/asm-i386,并在文件pgable-2level-defs.h中定义了二级页表的基本结构