C++:虚拟地址空间布局

对于每一个进程都会对应一个虚拟地址空间,对于32位的操作系统(其指令的位数最大为32位,因此地址码最多32位),虚拟地址空间的大小为2^{32}B即0~4GB的虚拟地址空间,其中内核空间为1GB,64位操作系统同理。

由于每个进程都不能直接访问内核空间,而是通过系统调用间接进入内核,因此,所有的进程都共享内核空间。而每个进程都拥有各自的用户空间,各个进程之间不能相互访问彼此的用户空间。因此,对每一个具体的进程而言,都拥有4GB的虚拟地址空间。

一个程序在经过编译、链接之后形成的地址空间是一个虚拟的地址空间,只有当程序运行的时候才会分配具体的物理空间。由此我们可以得知,程序的虚拟地址相对来时候是固定的,而物理地址则随着每一次程序的运行而有所不同。

对于内核空间而言,它与物理内存之间存在一个简单的线性关系,即存在3GB的偏移量。在Linux内核中,这个偏移量叫做PAGE_OFFSET。如果内核的某个物理地址为x,那么对应的内核虚拟地址就为x+PAGE_OFFSET。

对于用户空间而言,它与物理内存之间的映射远不止这么简单。与内核空间和物理空间的线性映射不同的是,分页机制将虚拟用户空间和物理地址空间分成大小相同的页,然后再通过页表将虚拟页和物理页块映射起来。

程序使用的地址空间要是连续的。

虚拟地址空间
操作系统给进程描述的一个虚假的地址空间,通过struct mm_struct结构体描述的虚拟地址空间。

使用虚拟地址空间的原因
若进程直接使用物理内存,会造成大量的内存碎片,导致资源利用率较低,并且缺乏访问的安全性。
注意:同一变量地址相同,其实是虚拟地址相同,内容不同是被映射到不同的物理地址上了。

虚拟地址空间的作用
1.方面编译器和操作系统安排程序的地址;
2.方便实现各个进程空间之间的隔离,互不干扰,因为每个进程都对应自己的虚拟地址空间;
3.实现虚拟存储,从逻辑上扩大了内存。

管理虚拟地址与物理地址的方法
分页&虚拟地址空间

虚拟地址空间映射到物理内存上的过程
首先我们使用一个虚拟地址向进程提供一个连续的完整的地址使用,通过页表映射到物理内存的各个区域,并且这些物理区域可以不用连续,实现了数据在物理内存上的离散式存储,提高了内存的利用率,并且虚拟地址空间可以对地址访问进行控制,提高访问安全性。

虚拟地址空间布局

1 保留区(受保护的地址)
保留区即为受保护的地址,大小为128M,位于虚拟地址空间的最低部分,未赋予物理地址(不会与内存地址相对应,因此其不会放任何内容)。任何对它的引用都是非法的,用于捕捉使用空指针和小整型值指针引用内存的异常情况。大多数操作系统中,极小的地址通常都是不允许访问的,如NULL。C语言将无效指针赋值为0也是出于这种考虑,因为0地址上正常情况下不会存放有效

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值