浅谈linux下的进程地址空间(虚拟地址/线性地址)

目录

什么是地址空间 - 虚拟地址空间

地址空间是如何设计的

为什么要有地址空间


什么是地址空间?

示例:

运行之后发现:同一个变量,同一个地址,在运行一段时间后,竟然会在同一时间出现两个不同的值?这是完全违背常理的,按道理来说一个 int类型 ,只能存储一个整数,为什么这里会出现两个完全不同的值呢???

要想了解这个问题,我们需要先了解一些东西。

linux下的地址空间:注意,这里指的是虚拟地址空间

【说明】
1.栈区(stack):在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。栈区主要存放运行函数而分配的局部变量、函数参数、返回数据、返回地址等,栈是向下增长的。

⒉.共享区:内存映射段是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口创建共享共享内存,做进程间通信。

3.堆区:堆用于程序运行时动态内存分配,堆是可以上增长的。一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。分配方式类似于链表。

4.数据段:--存储全局数据和静态数据。(未初始化/初始化数据)

5.代码段:--可执行的代码/只读常量。(正文代码)

上述的地址空间,也可以通过代码验证:示例:

打印结果如下:可以发现的确是符合进程空间地址排布规律的,地址也是由低到高进行增长的。(注:这里栈区之所以很大,是因为使用的是云服务器)

        上述的进程地址空间被称为 --- 虚拟地址空间 / 线性地址空间,它并不是实际上存储数据的物理内存空间,而是一种Linux下的内核数据结构,并且每一个进程都有独立私有的虚拟地址空间。

这里在Linux内核的源码中也有体现:进程的虚拟地址空间

那么如何管理各个区域呢?

在一个范围内定义start,end本质上就是在进行区域划分

所谓的范围变化,本质其实就是对start or end标记值 + -  特定的范围即可

地址空间是Linux内核数据结构,它里面一定有区域划分
 


地址空间是如何设计的

我们在虚拟地址和物理内存之间会设计一个页表,来维系二者的关联。

我们可以把各个区域及其对应的地址通过页表映射到不同的物理内存中,也就是说页表是维护映射关系的

这种映射关系是来维护虚拟地址和物理地址之间的的一种映射关系

换句话说,每个进程即使它的虚拟地址空间是完全一样的,但是只要它的页表映射关系是不同的,映射到物理内存的不同区域,那么它们就可以做到每个进程是具有独立性的

注:这里的页表是底层是哈希表,存储的是key_value结构,左边存储的的虚拟地址,右边存储的是物理内存地址


回答最开始的现象,为什么同一个地址,在同一个时刻,同时读取的时候,出现不同的值?

是因为这里的地址,绝对不是物理内存的地址,而是虚拟地址(线性地址)

所以,几乎所有的语言,如果它有”地址“的概念,那么这个地址一定不是物理地址,而是虚拟地址

        子进程继承了父进程大部分属性,页表和地址空间都相同,刚开始父进程对应的全局变量g_val的虚拟地址被映射到了物理内存上

        创建子进程的时候,因为页表的映射关系相同,此时父进程与子进程指向的是同一个变量g _val,所以地址相同,甚至值也相同

        但是当子进程尝试去修改g_val,因为要保障进程的独立性,当操作系统识别到当前的子进程想去通过页表去访问g_val,想要写入的时候

        那么操作系统会重新开辟一块空间,然后有必要的情况下,拷贝原来的值,然后再更改子进程的映射关系,防止子进程修改到原来地址的g_val

        完成更改之后,因为虚拟地址并不受影响,所以虚拟地址的值是相同的,但是物理数据经过页表的映射,被映射到了不同的区域,所以看到的g _val的值是不同的

补:最开始创建指向同一个位置,当子进程尝试去做修改的时候,才发现地址是不同的,这种策略叫做写时拷贝


深入了解虚拟地址空间:

当我们的程序,在编译的时候,形成可执行程序的时候,没有被加载到内存中的时候,其实已经有地址了! !

可执行程序其实编译的时候,内部已经有地址了!

地址空间不要仅仅是系统内部要遵守的,其实编译器也要遵守!

即编译器编译代码的时候,就已经给我们形成了各个区域代码区,数据区,...并且,采用和Linux内核中一样的编址方式,给每一个变量,每一行代码都进行了编址,故,程序在编译的时候,每一个字段早已经具有了一个虚拟地址!

物理内存中,可执行程序内部的地址,依旧用的是编译器编译好的虚拟地址

当程序加载到内存的时候,每行代码,每个变量边具有了一个物理地址,外部的
 

1.进程访问数据时,地址空间和页表(虚拟地址的一部分)会被编译时生成的虚拟地址填充,页表(物理地址的一部分)会被加载时产生的物理地址填充。

2例子:假设函数A调用函数B
此时,进程开始运行,cpu拿到的是编译时函数A产生的虚拟地址,通过函数A的虚拟地址映射到了物理内存
此时,访问内存空间,通过函数A中存储B函数的虚拟地址,获现到了的B函数的虚拟地址,再次通过映射关系访问到B函数(其中,A函数调用B函数,编译时A函数中一定会存储B函数的虚拟地址)
 


为什么要有地址空间

1.保障安全

历史原因:

        在当初,可执行程序被加载到内存中,进程是可以直接访问物理内存的,但是我们需要明白,内存本身是随时都可以被修改的,假如出现野指针的问题,进程之间是会被相互干扰,此时安全是很难保障的。

于是,现代计算机在此基础之上,提出了以下方式,虽然通过虚拟地址最终还是会访问到了物理内存,但是需要映射,而页表会对指针进行监测,如果出现非法访问,是可以禁止映射的。

凡是非法的访问或者映射,系统都会识别到,并终止你这个进程,此时有效的保护了物理内存

因为地址空间和页表是系统创建并维护的,也就意味着凡是想使用地址空间和页表进行映射,也一定要在OS的监管之下来进行访问!!

也就保护了物理内存中的所有的合法数据,包括各个进程,以及内核的相关有效数据!
 

2.方便管理

a.解耦合

因为有地址空间的存在,因为有页表映射的存在,我们的物理内存中,可以对未来的数据进行任意位置的加载

物理内存的分配就可以和进程的管理,做到没有任何关系!!

内存管理模块 vs 进程管理模块就完成了
 

注:所以,我们在C、C++语言上,new,malloc空间的时候,本质是在虚拟地址空间上申请的

因为如果我申请了物理空间,但是如果我不立马使用? 是不是空间的浪费呢?  是的!!

本质上,(因为有地址空间的存在,所以上层申请空间,其实是在虚拟地址空间上申请的,物理内存可以甚至一个字节都不给你! !而当你真正进行对物理地址空间访问的时候,才执行内存的相关管理算法,帮你申请内存,构建页表映射关系),然后,再让你进行内存的访问。这都是由操作系统,自动完成,用户,包括进程,完全0感知 ---缺页中断!
 

b.有序性

因为在物理内存中理论上可以任意位置加载,那么物理内存中的几乎所有的数据和代码在内存中是乱序的!

但是,因为页表的存在,它可以将地址空间上的虚拟地址和物理地址进行映射,那么在进程视角所有的内存分布,都可以是有序的!!

地址空间+页表的存在可以将内存分布,有序化!
 

c.独立性

通过进程映射到不同的物理内存,很容易做到让不同的进程具有独立性

地址空间+页表的存在可以实现进程的独立性


其实这也符合linux下,一切皆文件的概念

上帝视角下,内存可以任意读写,那么我们的非法访问也就是权限不够,也就是Linux下,一切皆文件的概念

注:以上仅代表个人观点,仅供参考

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/770873.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

阿里云短信平台收费价格表,短信服务优惠0.032元一条

2024年阿里云短信服务优惠价格表,阿里云短信多少钱一条?低至0.01元一条,200条短信仅需2元,最高可领2000条短信免费赠送,短信套餐包2000条、5000条、5万条等均有活动,阿里云百科aliyunbaike.com整理2024年最…

数字乡村战略实施:科技引领农村经济社会全面发展

随着信息技术的快速发展,数字化已经成为推动经济社会发展的重要力量。在乡村振兴战略的大背景下,数字乡村战略的实施成为了引领农村经济社会全面发展的关键。本文将从数字乡村战略的内涵、实施现状、面临挑战及未来展望等方面,探讨科技如何引…

MySQL数据库备份策略与实践详解

目录 引言 一、MySQL数据库备份的重要性 (一)数据丢失的原因 (二)数据丢失的后果 二、MySQL备份类型 (一)根据数据库状态 (二)根据数据的完整性 (三)…

线程的状态:操作系统层面和JVM层面

在操作系统层面,线程有五种状态 初始状态:线程被创建,操作系统为其分配资源。 可运行状态(就绪状态):线程被创建完成,进入就绪队列,参与CPU执行权的争夺。或因为一些原因,从阻塞状态唤醒的线程…

CCF-CSP认证考试 202212-2 训练计划 100分题解

更多 CSP 认证考试题目题解可以前往:CSP-CCF 认证考试真题题解 原题链接: 202212-2 训练计划 时间限制: 1.0s 内存限制: 512.0MB 问题背景 西西艾弗岛荒野求生大赛还有 n n n 天开幕! 问题描述 为了在大赛中取得…

【Linux】进程的基本概念(进程控制块,ps命令,top命令查看进程)

目录 01.进程的基本概念 程序与进程 进程的属性 02.进程控制块(PCB) task_struct的内容分类 组织进程 03.查看进程 ps命令 top指令 在计算机科学领域,进程是一项关键概念,它是程序执行的一个实例,是操作系统的…

Mybatis的核心配置文件

MyBatis的全局配置文件mybatis-config.xml,配置内容如下: properties(属性)settings(全局配置参数)typeAliases(类型别名)typeHandlers(类型处理器)objectFa…

面试知识汇总——垃圾回收器(分代收集算法)

分代收集算法 根据对象的存活周期,把内存分成多个区域,不同区域使用不同的回收算法回收对象。 对象在创建的时候,会先存放到伊甸园。当伊甸园满了之后,就会触发垃圾回收。 这个回收的过程是:把伊甸园中的对象拷贝到F…

【物联网】Qinghub Kafka 数据采集

基础信息 组件名称 : kafka-connector 组件版本: 1.0.0 组件类型: 系统默认 状 态: 正式发布 组件描述:通用kafka连接网关,消费来自kafka的数据,并转发给下一个节点做相关的数据解析。 配置文…

网络七层模型之物理层:理解网络通信的架构(一)

🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 🍚 蓝桥云课签约作者、上架课程《Vue.js 和 E…

如何忽略Chrome最小字号的限制

通过控制台调整字体大小时,可以发现即便设置了小于12px的字号,也并不会变小,这是因为Chrome默认最小字号为12px。 在Chrome设置中的外观选项卡中可以发现,默认字体是16px。将最小字号改为0,就能随意设置小于12px的字号…

spring boot商城、商城源码 欢迎交流

一个基于spring boot、spring oauth2.0、mybatis、redis的轻量级、前后端分离、防范xss攻击、拥有分布式锁,为生产环境多实例完全准备,数据库为b2b2c设计,拥有完整sku和下单流程的商城 联系: V-Tavendor

文件编辑命令—vim

1.vim vim 是vi的升级版本.vi 文件名(vi方向键用不了) vim 的官方网站 (welcome home : vim online) 自己也说 vim 是一个程序开发工具而不是文字处理软件。 2.安装vim sudo apt install vim 如果出错了:apt update:刷新软件源; 出现"无法获得锁 之类的"sudo rm 文件…

后端常问面经之并发

volatile 关键字 volatile关键字是如何保证内存可见性的?底层是怎么实现的? "观察加入volatile关键字和没有加入volatile关键字时所生成的汇编代码发现,加入volatile关键字时,会多出一个lock前缀指令”lock前缀指令实际上相…

2015年认证杯SPSSPRO杯数学建模D题(第二阶段)城市公共自行车全过程文档及程序

2015年认证杯SPSSPRO杯数学建模 D题 城市公共自行车 原题再现: 城市交通问题直接影响市民的生活和工作。在地形平坦的城市,公共自行车出行系统是一种很好的辅助手段。一般来说,公共自行车出行系统由数据中心、驻车站点、驻车桩、自行车&…

吴恩达深度学习笔记:浅层神经网络(Shallow neural networks)3.1-3.5

目录 第一门课:神经网络和深度学习 (Neural Networks and Deep Learning)第三周:浅层神经网络(Shallow neural networks)3.1 神经网络概述(Neural Network Overview)3.2 神经网络的表示(Neural Network Representation…

【Java八股面试系列】中间件-Redis

目录 Redis 什么是Redis Redis解决了什么问题 Redis的实现原理 数据结构 String 常用命令 应用场景 List(列表) 常用命令 应用场景 Hash(哈希) 常用命令 应用场景 set(集合) 常见命令​编辑 应用场景 Sorted Set(有序集合) 常见命令​编辑 应用场景 数据持…

idea中gradle编译下运营main方法报CreateProcess error=206

问题描述 CreateProcess error206 文件名或扩展名太长 问题分析 解决方案 build.gradle文件里添加 buildscript {repositories {maven {url "https://plugins.gradle.org/m2/"}}dependencies {classpath "gradle.plugin.ua.eshepelyuk:ManifestClasspath:1.…

Pandas操作MultiIndex合并行列的Excel,写入读取以及写入多余行及Index列处理,插入行,修改某个单元格的值

Pandas操作MultiIndex合并行列的excel,写入读取以及写入多余行及Index列处理 1. 效果图及问题2. 源码参考 今天是谁写Pandas的 复合索引MultiIndex,写的糊糊涂涂,晕晕乎乎。 是我呀… 记录下,现在终于灵台清明了。 明天在记录下直…

【Spring】IoCDI详解

1. IoC详解 前面提到过IoC就是将对象的控制权交由Spring的IoC容器进行管理,由Spring的IoC容器创建和销毁bean,那么既然涉及到容器,就一定包含以下两方面功能: bean的存储bean的获取 1.1 类注解 Spring框架为了更好地服务应用程…