【Linux】Linux 操作系统 - 14 , 程序地址空间竟然是这样 ?? 一文彻底搞懂进程虚拟地址空间初识(一) !

一文搞懂Linux进程虚拟地址空间


一、虚拟地址


  什么是虚拟地址 ? 什么是物理地址 ?

在这里插入图片描述

// 有这样一个代码

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

//全局变量 , 父和子都可用
int global = 100;

int main()
{
	printf("我是父进程 , 我的 pid = %d , 我的父进程 pid = %d , global = %d , &global = %p\n", getpid(),getppid(),global,&global);
	printf("-----------------------------------------------------------------------\n");
	//创建子进程 
	pid_t id = fork();		

	if(id < 0)
	{
		printf("fork err !\n");
		return 1;
	}	
	else if(id == 0)
	{
		//child
		while(1)
		{
			printf("我是子进程 , 我的 pid = %d , 我的父进程 pid = %d , global = %d , &global = %p\n",getpid() , getppid(),global++,&global);
			sleep(1);
			//子进程修改全局 global 
		}
	}	
	else
	{
		//father
		while(1)
		{		
			printf("我是父进程 , 我的 pid = %d , 我的父进程 pid = %d , global = %d , &global = %p\n",getpid() , getppid(),global,&global);
			sleep(1);
		}
	}

	return 0;
}

在这里插入图片描述

在这里插入图片描述


二、什么是进程虚拟地址空间 ?


地址空间的分布图
  在这里插入图片描述

以上的图只是形象的划分 , 那么在 Linux 操作系统中是怎样做到这样的划分的呢 ?

1. 怎么划分各个区域 ?

  进程虚拟地址空间分为很多区域 , 有 : 代码区 , 数据区 , 栈区 , 堆区 , 共享区 !

  那这些区域在系统中怎么被划分呢 ?

在这里插入图片描述


2 . 进程虚拟地址空间是什么 ?


答 : 是一个数据结构 ! mm_struct

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


3 . 本小节要知道的内容

在这里插入图片描述


三、深入剖析进程虚拟地址空间

1 . 为什么进程虚拟地址空间要被管理呢 ?


  这里讲一个例子 :

在这里插入图片描述


2 . 虚拟地址空间与内存

2.1 . 虚拟地址空间怎么骗程序 ?

在这里插入图片描述


2.2 . 虚拟地址空间怎么与内存交互呢 ? (页表初识)


答 : 通过页表 !

页表初识

在这里插入图片描述

页表映射

在这里插入图片描述


为什么父或子进程中变量地址一样 , 值不一样呢 ? (虚拟地址空间底层) (回答 一 中的问题 !)


  这里举的例子是 : 一 中的代码所面临的问题 .

在这里插入图片描述

为什么 ???

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1 . 回答问题1 , 地址为什么一样 ?

在这里插入图片描述


2 . 回答问题2 , 为什么一方改变 , 一方值不变 ?

在这里插入图片描述

在这里插入图片描述


本节重点

在这里插入图片描述


3 . 进程虚拟地址空间在 Linux 中的存在形式


  前面也提到了 , 一个进程有自己的 mm_struct , 这个 mm_struct 里面又是起始地址和结束地址 .


  那进程也会有很多呀 , 那 mm_struct 要不要被管理起来呢 ? 答 : 要 !

  linux内核使用 vm_area_struct 结构来表示一个独立的虚拟内存区域(VMA) .

即 : 进程虚拟地址空间中的每一个区域都用 vm_area_struct 这个数据结构管理起来 !

在这里插入图片描述
在这里插入图片描述


4 . 为什么要有进程虚拟地址空间呢 ?


  有的人可能会想 , 进程虚拟地址空间最终访问数据不是还有映射物理内存吗 ?? 那就意味着最终还是要用物理内存吗 ?? 为什么不直接去访问呢 ??

1 . 让地址从 “无序” 变 “有序”


这里的有序 , 不是绝对有序 !


  看一个代码 :

int main()
{

   // 堆上申请空间 
   char *heap_mem = (char*)malloc(10);
   char *heap_mem1 = (char*)malloc(10);
   char *heap_mem2 = (char*)malloc(10);
   char *heap_mem3 = (char*)malloc(10);
   printf("heap addr: %p\n", heap_mem); //heap_mem(0), &heap_mem(1)
   printf("heap addr: %p\n", heap_mem1); //heap_mem(0), &heap_mem(1)
   printf("heap addr: %p\n", heap_mem2); //heap_mem(0), &heap_mem(1)
   printf("heap addr: %p\n", heap_mem3); //heap_mem(0), &heap_mem(1)

   return 0;


}

在这里插入图片描述

在这里插入图片描述


2 . 虚拟内存可以保护物理内存

  将从以下两方面回答 !

2.1 . 什么是野指针 ?

在这里插入图片描述

2.2 . 为什么改变字符串常量会崩溃 ?

在这里插入图片描述


3 .让进程管理和内存管理解耦合

在这里插入图片描述


总结

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值