虚拟内存是计算机系统内存管理的一种技术,它使应用程序认为它拥有连续的可用的内存,而实际上它通常被分隔成多个物理内存碎片,还有部分存储在外部磁盘存储器上,在需要时进行数据交换。
程序使用的内存地址叫做虚拟内存地址,实际存在硬件的空间地址叫物理地址
进程通过虚拟地址来访问实际的物理地址
好处
可以弥补物理内存大小的不足
一定程度的提高反映速度
为每个进程提供了一致的地址空间,简化内存管理
程序根据逻辑划分成若干个段,如数据段、代码段等。目的是为了能更好的满足用户的需要。
分段机制下虚拟地址由两部分组成:段选择子(包括段号和一些标识位) 和 段内偏移量
虚拟地址通过 段表 与物理地址进行映射,每一个段在段表中会对应一个段基地址,我们通过 段基地址 + 偏移量 就可以得到物理地址
缺点:内存碎片、内存交换效率低
分页是把整个虚拟内存和物理内存划分为一段段固定尺寸的大小,这样一个尺寸固定的内存空间叫页。
分页机制下虚拟地址分为页号 和 页内偏移
虚拟地址 与 物理地址 之间通过页表来映射,页号作为页表的索引得到对应的物理页号,页表还会保存物理页每页所在物理内存的基地址,通过基地址 + 页内偏移 得到物理地址
在linux下,每一页大小为4KB
在32位环境下,虚拟地址空间有4GB,那么需要2^20(1M)个页,每个页表项需要4个字节,那么4GB空间的映射就需要有4MB 的内存存储页表
每个进程都是有⾃⼰的虚拟地址空间的,100 个进程的话,就需要 400MB 的内存来存储⻚表,这是⾮常⼤的内存了,但是因为程序不可能用到所有的虚拟内存,所以会存在部分页表项是空的。所以引入多级页表
将2^20个页分为1024个一级页表,一级页表的每一项对应到一个二级页表的地址,每一个二级页表又包含1024个页表项,形成二级分页。
这样4KB的一级页表就覆盖了全部虚拟地址,二级页表只在需要时创建。把二级分页推广到多级页表,页表的占用空间更少了。
多级页表的存在会降低虚拟地址和物理地址之间的转换效率,于是在CPU中加了一个专门存放程序最常访问的页表项的Cache,就是TLB(快表,页表缓存)
在CPU中,做将虚拟内存地址转换成物理地址的⼯作。
程序中使用的地址均是虚拟内存地址,都会引发MMU进行查表和地址转换操作。
段⻚式内存管理实现的⽅式:
段页式地址变换的数据结构是:每个程序一个段表,每个段有一张页表
此时 虚拟地址 到 物理地址 的转换需要三次内存访问:
第一次访问段表,得到页表起始地址
第二次访问页表,得到物理页号
第三次将物理页号和页内偏移结合,得到物理地址