在cpu中有专门的寄存器(cr3)来存储页表的地址,当进程离开cpu时会将页表一起带走(页表也是进程上下文的一部分)。
页表存储的位置是物理内存
页表是进程管理和内存管理之间的纽带,将进程管理模块和内存管理模块进行解耦合。
这里的解耦合:
解耦合进程管理和内存管理的方法主要有以下几种:
虚拟地址空间:虚拟地址空间是进程管理和内存管理解耦合的关键。每个进程都有自己的虚拟地址空间,可以独立地访问和管理自己的内存。这样可以实现进程之间的隔离和保护,避免进程之间的数据泄露和破坏。
独立的内存管理器:将进程管理和内存管理模块解耦可以通过为每个进程创建一个独立的内存管理器来实现。每个内存管理器负责管理该进程的虚拟地址空间和物理内存,这样可以实现进程之间的独立性和隔离性。
共享内存:在某些情况下,进程之间可能需要共享一些数据。为了实现进程之间的通信和协作,可以使用共享内存技术。通过将一些内存区域映射到多个进程的虚拟地址空间中,可以实现进程之间的数据共享和通信。
页表将无序变为有序:通过连续的空间,把处于磁盘上的各种切片信息整理起来。
虚拟内存页 | 物理内存页 | 状态位 | 其他属性 |
---|---|---|---|
虚拟地址 | 物理地址 | W?R? | 页面大小、指针 |
ox7777ffffff | 0x123456 |
页表(Page Table)中存储的是页表项(Page Table Entry):
页面的大小:这是在操作系统层面规定的,每个页面的大小会影响页表中的条目数量和存储需求。
虚拟页号(Virtual Page Number,VPN):表示页面在虚拟地址空间中的位置。
物理页号(Physical Page Number,PPN):表示页面在物理地址空间中的位置。
标志位:用于描述页面的状态或属性。如可读、可写、可执行、脏页(内容已经被修改)、保护位(指示访问权限)、有效位(指示页面是否已分配)、状态位(0表示页面不在内存中,还有在磁盘中的数据没被读取,处于缺页状态)等。
表头指针:指向下一级页表(如果有的话)或者指向数据或代码的物理地址。
访问模式信息:包括读模式、写模式、日期、使用状态等。
帧号:在分页系统中,每个物理内存帧都有一个唯一的帧号,页表条目中可能会包含这个帧号,以便于快速访问物理内存中的对应帧。
页表项的日期和过期时间:这可以帮助操作系统判断页面是否仍然有效,以及何时可能需要替换或更新页面。
页帧(Page Frame)和页框(Page Frame)在计算机系统中是指相同的概念,它们都是指内存中的固定大小的存储块。它们的主要作用是用来存储虚拟地址空间中的页面(Page)。
在内存管理中,虚拟内存被划分为固定大小的页面,通常为4KB或者8KB。而物理内存也被划分为与虚拟内存相同大小的页帧或页框。每个页面在内存中有一个相对应的页帧或页框。
当进程在运行过程中需要访问某个虚拟地址时,操作系统通过页表将虚拟地址转换为对应的物理地址。页表的一项记录了虚拟页面和物理页帧之间的映射关系。通过这种映射,可以实现虚拟内存的页面与物理内存的页帧之间的关联。
总之,页帧和页框是指物理内存中的固定大小的存储块,用来存放虚拟内存中的页面。它们的概念基本相同,只是在不同的文献或不同的背景下使用的术语可能会有所不同。
页结构体通常是在操作系统的内核中使用的数据结构,用于描述和管理页面的详细属性和信息。在一些实现中,页表中的每个页表项可能会引用页结构体,以实现更多的信息存储和管理功能。
页结构体是虚拟内存管理中的一个概念,用于描述一个页面的属性和信息。它通常包含以下字段:
虚拟页号(Virtual Page Number,VPN):标识页面在虚拟地址空间中的位置。
物理页号(Physical Page Number,PPN):如果页面已经分配了物理内存,物理页号表示页面在物理地址空间中的位置;如果页面未被分配,则物理页号可以为空或为无效值。
标志位(Flags):用于描述页面的状态或属性,常见的标志位包括可读、可写、可执行、脏页(内容已经被修改)、保护位(指示访问权限)等。
计数器(Counter):用于统计页面的使用情况,如页面被访问的次数,可用于页面置换算法的决策。(引用计数)
其他信息:根据具体的需求,页结构体可能还包含其他与页面管理相关的信息,如页面所属进程、页面大小、页面访问权限等。
页结构体在内核中使用,用于管理虚拟内存和物理内存之间的映射关系,以及执行页面置换和页面分配等操作。
在分页系统中,有两种页号的映射关系:虚拟页号(Virtual Page Number,VPN)和物理页号(Physical Page Number,PPN)。虚拟页号是进程中使用的虚拟地址中的页号部分,而物理页号是物理内存中实际页面的页号。
页号的映射是通过页表(Page Table)来实现的。页表是一种数据结构,存储了虚拟页号到物理页号之间的映射关系。在分页系统中,每个进程都有自己独立的页表,用于将进程的虚拟地址转换为对应的物理地址。
当进程访问一个虚拟地址时,操作系统会根据该虚拟地址中的虚拟页号,查找进程的页表,获取对应的物理页号。这个物理页号指示了在物理内存中的实际页面。
虚拟页号的范围通常较大,可以超过物理内存的大小。为了解决这个问题,操作系统使用了页面置换算法(Page Replacement Algorithm),以及其他技术(如内存分页和分段结合)来管理虚拟页号到物理页号的映射,以最大程度地利用有限的物理内存,并允许进程的页面在磁盘和内存之间进行动态迁移。
总之,虚拟页号和物理页号的映射关系由进程的页表确定。通过页表的查询,虚拟页号可以被映射到对应的物理页号,从而确定物理内存中的实际页面位置。
是的,有可能在虚拟地址映射的物理地址没有被分配空间。这种情况通常发生在以下几种情况下:
延迟分配:操作系统采用延迟分配策略时,虚拟地址可能先于物理地址分配。在这种情况下,当进程首次访问虚拟地址所指向的数据时,操作系统才会分配对应的物理内存空间,并将虚拟地址与物理地址建立映射。
页面错误:如果进程访问的虚拟地址所映射的物理地址尚未分配,或者物理页未加载到内存(缺页中断)中,会触发页面错误(Page Fault)。页面错误通常由操作系统处理,操作系统会将虚拟地址所需的数据从磁盘上加载到内存中,并更新页表以建立映射关系。通过这种方式,虚拟地址最终映射到了物理地址空间。
需要注意的是,虚拟地址空间是比物理地址空间更为广阔的概念。在实际的内存中,可能仅有部分虚拟地址被分配了物理内存空间,而其他虚拟地址可能没有相应的物理内存映射。当进程访问这些尚未映射的虚拟地址时,就会发生页面错误,操作系统会根据需要将相应的数据加载到内存中。
在fork()
函数中,子进程会复制一份父进程的页表,但是子进程的页表和父进程的页表并不完全相同。
当fork()
函数被调用时,操作系统会为新进程分配一个新的进程标识符(PID)并创建PCB,在PCB中指向一个与父进程相同的虚拟地址空间。然后,新进程会复制一份父进程的页表,并将自己的权限信息(读/写/只读)添加到页表中。
由于新进程和父进程有不同的权限,因此它们对内存的访问方式也不同。父进程只能读取自己的页表,而子进程可以读取自己的页表和父进程的页表。子进程的页表中包含了父进程页表中所有页面的副本,但是这些页面的权限信息已经被修改为子进程自己的权限信息。
如果要进行写操作,或者父进程要对自己原本的数据进行修改,操作系统会捕获这一事件,并为正在进行写操作的进程复制相应的内存页,创建一个新的物理页并让该进程的虚拟地址映射指向这个新页。这样,父进程和子进程之间的数据就分开了,不再相互共享。(在后续进程创建中的写实拷贝中重点介绍)
这个知识点没有那么简单,在后续的学习会逐渐理解。
我自己目前的理解,因为有标志位记录原本父进程数据是只读还是读写,子进程为要对原本可写的数据进行操作就能被操作系统知道,这时就会发生物理内存页的复制,父子进程页表的虚拟地址是自身的属性,映射的物理地址才是关键,所以也出现了一样的虚拟地址不同的物理地址
(在进程创建中介绍)
(在文件系统后的文件的写入与写回中介绍)