内存管理-虚拟内存

虚拟地址怎么映射到物理地址?内存分段?内存分页?现代操作系统使用的是哪个?

什么是虚拟地址?

区分虚拟地址和进程的虚拟内存空间

进程的虚拟内存空间

  • 代码段:用于存放进程程序二进制文件中的机器指令;
  • 数据段:用于存放二进制文件中定义的已初始化的全局变量和静态变量;
  • BSS段:用于存放二进制文件中定义的未初始化的全局变量和静态变量;
  • 堆:用于存放程序运行中动态申请的堆;
  • 文件映射与匿名映射区:用于存放动态链接库中的代码段,数据段,BSS段以及通过mmap系统调用映射的共享内存区;
  • 栈:用于存放函数调用过程中的局部变量,函数参数及返回值。

内核态和用户态地址划分

32位:

  • 用户态:0x0000 0000 - 0xC000 0000
  • 内核态:0xC000 0000 - 0xFFFF FFFF

64位:

  • 用户态:0x0000 0000 0000 0000 - 0x0000 7FFF FFFF F000
  • 内核态:0xFFFF 8000 0000 0000 - 0xFFFF FFFF FFFF FFFF

对于64位详细解释:

64位机器上的寻址范围为2^64,但是在实际使用中只使用了其中的低48位来表示虚拟内存地址,多出的16位形成地址空洞。

  • 如果一个虚拟内存地址高16位全部为0,则是一个用户空间的虚拟内存地址;
  • 如果一个虚拟内存地址高16位全部位1,则是一个内核空间的虚拟内存地址;
  • 如果一个虚拟内存地址高16即有0又有1,则是一个非法的内存地址。

为什么要用虚拟地址?

内存分段

flowchart LR
    id1[虚拟地址] --> id2[段选择因子]
    id1 --> id3[段内偏移量]
    id2 --> id4[段号]
    id2 --> id5[标志位]

段号:用作段表的索引;

段内偏移量:段基地址加上段内偏移量得到物理内存地址;

段表是什么?

分段的优缺点

内存碎片问题

如何解决内存碎片问题

内存分页

分页的优缺点

缺页异常

多级页表

如果4GB的虚拟地址全部映射到了物理内存上的话,二级页表占用空间确实更大了,但是我们往往不会为一个进程分配那么多内存。

对于不分级页表,我们也不会为一个进行分配那么多内存呀,为什么不采用不分级页表呢?

从页表的性质来看,保存在内存中的页表承担的职责是将虚拟地址翻译成物理地址。假如虚拟地址在页表中找不到对应的页表项,计算机系统就不能工作了。所以页表一定要覆盖全部虚拟地址空间,不分级的页表就需要有100多万(4MB)个页表项来映射,而二级分页则只需要1024个页表项。一级页表覆盖到了全部虚拟地址空间,二级页表在需要时创建。

TLB

段页式内存管理

内存的分段与进程的内存有什么联系?

内存的分段即:分段式管理。

虚拟空间分布中的分段即:内核态,用户态(代码段,全局变量,BSS,函数栈,堆内存,映射区)。


内存管理-虚拟内存
http://example.com/2025/05/13/OperatingSystem/内存管理-虚拟内存/
作者
ZhangHangming
发布于
2025年5月13日
许可协议