0


Linux 进程地址空间

在这里插入图片描述

进程地址空间


C/C++对空间的划分

在这里插入图片描述

  • 这个图中展示的内容是在内存吗? > 我们称这个区域为地址空间。

图示

在这里插入图片描述

#include<stdio.h>#include<stdlib.h>int val_1;//未初始化全局变量int val_2=100;//已初始化全局变量intmain(){printf("code address: %p\n",main);//代码区constchar*str="hello world";//字符常量区printf("str address: %p\n",str);//为什么是str,str就是保存的字符串常量的起始地址。printf("val_2 address: %p\n",&val_2);printf("val_1 address: %p\n",&val_1);char* mem=(char*)malloc(100);//堆区printf("heap address: %p\n",mem);printf("stack address: %p\n",&str);//栈区,局部变量在栈区}
  • 栈区的地址是向下增长,堆区的地址是向上增长。堆栈相对而升。
  • static 修饰的变量> 为什么用 static 修饰的变量,就不会随着函数调用而被释放?> 因为 static 修饰的局部变量,在编译时已经被编译到全局数据区了,所以才不会被释放。
  • 结论> 如果变量的地址是物理地址,不可能存在父子进程访问的变量地址相同但是值不同的现象。出现这样的现象称为线性地址或者虚拟地址。所以平时写得 C/C++用的指针,指针里面的地址,绝对都不是物理地址,而是称为虚拟地址。

地址空间

一个可执行程序有代码数据两部分,还会创建进程地址空间。每一个进程都有进程地址空间。

地址空间的概念

概念:所谓的进程地址空间,本质是一个描述进程可视范围的大小。地址空间内一定要存在各种区域划分,对线性地址进行 start 和 end 划分即可。地址空间本质是内核的一个数据结构对象,类似 PCB 一样,地址空间也是要被操作系统管理的:先描述,再组织。

主要组成部分

请添加图片描述

  • 页表 K(键) V(值) 结构 键值为虚拟地址,值为物理地址> 当程序运行时,就会根据页表中的虚拟地址来找到对应的物理地址。
  • 写时拷贝的本质:> 重新开辟空间,但是在这个过程中,左侧的虚拟地址是不变的,不影响虚拟地址;而是在物理内存中开辟了新空间,将更改的信息存储到这个空间中。所以就出现了虚拟地址相同而值不同的现象。

常见细节问题

  • 总线> CPU 与内存之间的线称为:系统总线> 内存和外设之间的线称为:IO 总线> 在 32 为计算机中,有 32 位的地址和数据总线。每一根总线只有 0,1 的概念。一共有 2^32 种状态。2^32*1byte=4GB,所以一个 32 位系统最多能装载 4GB 的内存空间。
  • 地址空间究竟是什么?- 什么叫做地址空间?> 地址总线排列组合形成的地址范围[0,2^32),- 如何理解地址空间上的区域划分?
  • 为什么要有进程地址空间?> > - 1. 让所有进程以统一的视角看待内存结构> - 1. 增加进程虚拟地址空间,可以让我们访问的内存的时候,增加一个转换的过程,在这个转换的过程中,可以对我们的寻址请求进行审查,所以一旦异常访问,我们直接拦截,该请求不会到达物理内存,保护物理内存。> - 1. 因为有地址空间和页表的存在,可以将进程管理模块和内存管理模块进行解耦合。
  • 页表结构是一个映射表。cr3 寄存器保存的是页表的起始地址(物理地址),这个地址是物理地址
  • 怎么知道进程的代码数据在不在内存?> 操作系统对大文件可以实现分批加载
  • 惰性加载> 操作系统对进程的加载策略为惰性加载的方式,
  • 缺页中断> 在页表中有一列为对应的代码和数据是否已经被加载到内存,如果显示不在,操作系统会触发缺页中断,操作系统会重新申请内存。(写时拷贝就是一种缺页中断)
  • 进程被创建的时候,是先创建内核数据结构呢?还是先加载对应的可执行程序呢?> 先创建内核数据结构

在这里插入图片描述

标签: linux java 运维

本文转载自: https://blog.csdn.net/2301_80122797/article/details/142101271
版权归原作者 Mike! 所有, 如有侵权,请联系我们删除。

“Linux 进程地址空间”的评论:

还没有评论