虚拟内存和地址空间

Posted better_hui

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了虚拟内存和地址空间相关的知识,希望对你有一定的参考价值。

目录

一、物理内存vs虚拟内存

二、物理内存空间和虚拟内存空间

三、32bit的地址空间

四、cpu位宽和cpu地址总线宽

五、虚拟内存地址空间划分

六、虚拟地址和物理地址的映射


 

 

img

早期的计算机程序都是直接跑在物理内存上的,这就要求程序大小不能超过物理内存的上限;

现代计算机为提高CPU使用率、并发执行多个程序、隔离程序间内存地址、打破物理内存上限,采用虚拟内存机制来运行程序

一、物理内存vs虚拟内存

物理内存就是实实在在的内存条。

虚拟内存是一个概念,对于一个程序来说,它包含了程序运行时可用的内存空间总和,包括共享的、非共享的、物理内存中的、存在分页中的等等。【虚拟内存映射 = 物理空间 + 硬盘空间 + 未使用的映射】

二、物理内存空间和虚拟内存空间

物理内存大小组成的地址空间就是物理内存空间。就是我们常说的RAM物理内存空间。可以看成一个连续的M个字节大小的数组。每个字节对应唯一的物理地址。

虚拟内存大小组成的地址空间就是虚拟内存空间。和物理内存空间一样,它也有地址空间。

三、32bit的地址空间

32位的操作系统为一个新创建的程序,分配一个4GB(2^32)大小的虚拟内存。这个过程就是创建了一个映射表,并不是真正的分配到物理内存上。

四、cpu位宽和cpu地址总线宽

虚拟内存的大小与实际的RAM没有关系,而是取决于cpu位宽 和 cpu地址总线宽

1、我们平时说的32位的cpu、64位的cpu ,指的就是cpu的位宽,表示的是一次能够处理的数据宽度。即一个时钟周期内cpu能够处理的2进制位数。其取决于寄存器的宽度

2、cpu地址总线宽度决定了直接寻址物理内存空间。如果cpu的地址总线是32位的,也就是它可以寻址 0 - 0xFFFFFFFF (4G)的物理地址。

3、cpu位宽 不等于 cpu地址总线宽度 。 16位的cpu的地址总线宽可以是20位

4、cpu访问任何存储单元必须知道其物理地址,所以在一定程序上,cpu总线宽影响了最大支持的RAM大小

 

五、虚拟内存地址空间划分

img

 

预留空间:从0x00000000到0x08048000的这段空间是预留的,是不能访问的,例如对空指针进行访问程序就会崩溃

只读段:程序运行时产生的指令放在此分段。同时这一段也保存了只读数据

.data读写段:存放初始化了且初始化值不为0的数据

.bss读写段:存放了未初始化 或 初始化值为0的数据

运行时堆:这段时间是不存在的,只有当程序运行起来后,new 或者 malloc之后才会分配内存,由低地址向搞地质增长

加载共享库:动态链接库,windows下是*.dll,Linux下是 *.so

stack : 函数或者线程都有独立的栈空间,由高地址向低地址增长

命令行参数和环境变量,命令行参数如main函数传参,环境变量如搜索头文件、库文件时默认的路径

 

六、虚拟地址和物理地址的映射

一个程序想要运行,必须运行在真实的物理内存之上,所以必须在虚拟内存地址和物理内存地址之间建立一种映射关系。

这种映射关系是由操作系统建立的,当程序访问虚拟地址的一个地址时,实际上是通过映射关系访问了真实内存的另外一个地址值。

这种映射机制需要硬件的支持——cpu中的内存管理单元(Memory Management Unit , MMU)利用存放在物理内存中的映射表动态翻译,这就是cpu虚拟寻址。

当程序试图访问地址空间的一个地址位置时,我们通过以下的假代码表示以下:

if(数据在物理内存中) { 虚拟地址转换成物理地址 读数据 } else { if(数据在磁盘中) { if(物理内存还有空闲) { 把数据从磁盘中读到物理内存 虚拟地址转换成物理地址 读数据 } else { 把物理内存中某页的数据存入磁盘 把要读的数据从磁盘读到该页的物理内存中 虚拟地址转换成物理地址 读数据 } } else { 报错 } }

以上是关于虚拟内存和地址空间的主要内容,如果未能解决你的问题,请参考以下文章

虚拟地址的高端内存

Linux 内核 内存管理虚拟地址空间布局架构 ② ( 用户虚拟地址空间组成 | 内存描述符 mm_struct 结构体源码 )

Linux 内存管理 (虚拟内存,进程地址空间)

进程地址空间与虚拟内存

Linux进程地址空间与虚拟内存

虚拟地址空间:用户空间和内核空间 物理内存管理:伙伴系统以及slab分配器