一个实际流程
假设一个进程访问了虚拟地址 0X12345678 (32位内存地址)。
1.首先,MMU 会将虚拟地址 0X12345678 分解为页号与页内偏移量两部分。假设当前系统使用4KB大小的页面,则页号为 0X12345(20位,十六进制 0X12345678 这个数据,第三个字节为 0X56, 转换为二进制为 0B 01010110,所以第三个字节高位为:0X0101, 低位为:0X0110,所以可以直接将0X56分割为0X5,0X6)。
2.接下来,MMU 会根据当前进程的页表(每个进程都会存在一个页表),进行查找虚拟地址和物理地址的映射关系。假设当前进程页表中记录了虚拟地址 0X12345000 到 0X45678000(物理地址)的映射关系,那么 MMU 则会将 0X12345 转换为物理地址 0X45678,并将页内偏移量 0X678 添加到物理地址上,从而得到最终的物理地址 0X45678678。
3.最后,当前进程就可以使用物理地址 0X45678678 进行访问物理内存中的数据。
注意:实际的虚拟地址到物理地址的转换可能会更加复杂,因为现代操作系统通常使用多级页表、TLB缓存等技术来优化地址转换的性能。
知识点扩展
页表
页表概念:
页表是操作系统中用于管理虚拟内存的数据结构之一。它是一个表格,其中每个条目对应于虚拟地址空间中的一个页面,记录了该页面在物理内存中的位置。当程序访问虚拟地址时,操作系统会使用页表将虚拟地址转换为物理地址,以便程序可以访问相应的内存。
页表通常由操作系统维护,每个进程都有自己的页表。在多道程序环境下,操作系统会根据需要切换不同进程的页表,以确保每个进程都能够访问自己的虚拟地址空间。
页表还可以用于实现虚拟内存的一些高级特性,例如页面置换、页面共享和内存保护等。通过使用页表,操作系统可以将物理内存和虚拟内存分离,从而提高系统的可用性和安全性。
页表查看方式:
Linux:
在 Linux 系统中,可以使用 pmap
命令来查看进程的页表信息。该命令可以显示进程的内存映射信息,包括虚拟地址、物理地址、权限等。
例如,要查看进程 ID 为 1234 的进程的页表信息,可以在终端中输入以下命令:
pmap -x 1234
该命令会输出进程的内存映射信息,其中包括每个内存区域的起始地址、大小、权限、映射文件等信息。在输出中,每个内存区域的页表信息会以类似下面的格式显示:
Address Kbytes RSS Dirty Mode Mapping
0000000000400000 132 4 0 r-x-- hello
0000000000600000 4 4 4 rw--- hello
00007f5d7d6d2000 132 4 4 r-x-- libc-2.23.so
00007f5d7d8f2000 2044 0 0 ----- libc-2.23.so
...
其中,Address
列显示了该内存区域的起始地址,Kbytes
列显示了该内存区域占用的内存大小,RSS
列显示了该内存区域的实际使用内存大小,Dirty
列显示了该内存区域的脏页数量,Mode
列显示了该内存区域的权限信息,Mapping
列显示了该内存区域所映射的文件或设备。
Windows:
在 Windows 系统中,可以使用 Process Explorer 工具来查看进程的页表信息。Process Explorer 是一款免费的系统监视工具,可以显示系统中所有进程的详细信息,包括内存使用情况、线程信息、句柄信息等。
要查看进程的页表信息,可以按照以下步骤操作:
-
下载并安装 Process Explorer 工具。
-
启动 Process Explorer 工具,找到要查看的进程,右键点击该进程,选择 “Properties”。
-
在弹出的对话框中,选择 “Performance” 选项卡,可以看到该进程的内存使用情况。
-
在 “Performance” 选项卡中,选择 “Virtual Memory”,可以看到该进程的虚拟内存使用情况,包括虚拟地址、物理地址、页表大小等信息。
需要注意的是,Process Explorer 工具只能查看当前正在运行的进程的页表信息,无法查看已经结束的进程的页表信息。此外,由于页表信息非常庞大,因此在查看大型进程的页表信息时,可能需要等待一段时间才能显示完整的信息。