虚拟地址空间理解

首先我们来看一下进程的空间分布图
虚拟地址空间理解_第1张图片
来看一段代码:

#include 
#include 
#include 
int g_val = 0;
int main()
{
pid_t id = fork();
if(id < 0){
perror("fork");
return 0;
}
else if(id == 0){ //child,子进程肯定先跑完,也就是子进程先修改,完成之后,父进程再读取
g_val=100;
printf("child[%d]: %d : %p\n", getpid(), g_val, &g_val);
}else{ //parent
sleep(3);
printf("parent[%d]: %d : %p\n", getpid(), g_val, &g_val);
}
sleep(1);
return 0;
}

//这个代码的运行结果是:
child[3046]: 100 : 0x80497e8
parent[3045]: 0 : 0x80497e8

我们可以发现:父子进程输出地址一样,但是内容不一样!
这个结果证明:这个地址不是物理地址。
所以这就引出了虚拟地址的概念。
明确一点:程序使用的地址空间要是连续的
虚拟地址空间:是操作系统给进程描述的一个虚假的地址空间,通过struct mm_struct结构体描述的虚拟地址空间。
为什么使用虚拟地址空间:若进程直接使用物理内存,会造成大量的内存碎片,导致资源利用率较低,并且缺乏访问的安全性。
注意:同一变量地址相同,其实是虚拟地址相同,内容不同是被映射到不同的物理地址上了。

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

你可能感兴趣的:(Linux,linux)