linux地址空间

地址空间

  • 内存空间示意图
  • 虚拟地址空间
    • 虚拟地址
    • 进程地址空间生命周期图解
    • 为什么要有地址空间呢?
  • 小结

内存空间示意图

进程是在内存中运行的,为了便于管理,不同的数据会存储在不同的区域,因此内存就被分为几部分,如下图所示:

在这里插入图片描述
而这些区域都存什么东西呢?我们有下面一段程序:

#include<stdio.h>2 #include<stdlib.h>3 4 int un_g_val;5 int g_val = 2;6 7 8 int main(int argc, char* argv[], char* env[])9 {10   printf("adress: %p\n",main);11   printf("init: %p\n",&g_val);12   printf("uninit: %p\n",&un_g_val);13   char *p1 = (char*)malloc(10);14   char *p2 = (char*)malloc(10);15   char *p3 = (char*)malloc(10); 16 17   printf("heap_p1: %p\n",p1); // 堆地址18   printf("heap_p2: %p\n",p2);19   printf("heap_p3: %p\n",p3);20   printf("stack_p1: %p\n",&p1); //栈地址21   printf("stack_p2: %p\n",&p2);22   printf("stack_p3: %p\n",&p3);23 24   int i = 0;25   for(i=0;i<argc;i++)26   {27     printf("argv[%d]:%p\n",i,argv[i]);28   }29                                                                                                                                                                         30   for(i=0;env[i];i++)31   {               32     printf("env[%d]:%p\n",i,env[i]);33   }          34   return 0;   }

这个程序打印了各种变量的地址,印证了地址空间是确实存在的!
在这里插入图片描述


我们再看这个代码能编过吗?

 11   //常量                                                                                                                                                                12   "hello world";               13   50;                          14   'xxxx;       

可以编译过,并且该东西是字符常量它会硬编码进代码(因为代码也不可更改),所以字符常量会在代码区。

虚拟地址空间

看下面一段代码:该程序创建了一个子线程,共享父进程的全局变量,子进程会更改全局变量。

  1 #include<stdio.h>2 #include<stdlib.h>3 #include<unistd.h>4 int g_val = 2;5 6  7 int main()8 {9   pid_t id = fork();10 11   if(id == 0)12   {13     //child14     int cnt = 0;15     while(1)16     {17       printf("I am a child, pid_id:%d,  ppid_id:%d , g_val:%d, &g_val:%p\n",getpid(),getppid(), g_val,&g_val);18 19       sleep(1);20       cnt++;21       if(cnt==5)22       {23         g_val = 200;24         printf("child chamge g_val 2 -> 200 success\n");25       }26     }27   }28   else29   {                                                                                                                                                                     30     //father31     while(1)32     {33       sleep(1);34       printf("I am a father, pid_id:%d,  ppid_id:%d , g_val:%d, &g_val:%p\n",getpid(),getppid(), g_val,&g_val);35     }36   }
I am a child, pid_id:20414,  ppid_id:20413 , g_val:2, &g_val:0x60105c
I am a father, pid_id:20413,  ppid_id:18692 , g_val:2, &g_val:0x60105c
child chamge g_val 2 -> 200 success
I am a child, pid_id:20414,  ppid_id:20413 , g_val:200, &g_val:0x60105c
I am a father, pid_id:20413,  ppid_id:18692 , g_val:2, &g_val:0x60105c

我们从运行的结果可以看出来,子进程修改全局变量后,子进程的值改变,父进程的值没变,但是全局变量的地址空间一样!!!

为什么会产生这种情况呢??
我们大胆猜测,程序打印的地址,一定不是物理地址,因为同一地址不可能存储两个不一样的值 。因为打印出来的是虚拟地址!!!

虚拟地址

每一个程序都有自己的虚拟地址空间,就像PCB一样,每一个程序都有一个属于自己的虚拟地址空间,记录着各种数据的位置,供操作系统使用。
如下图所示:代码在准备执行时,会编译成可执行程序,此时程序里面,即代码与代码是有地址的(这个地址就是虚拟地址),程序被加载到内存后:

  1. 首先系统会创建PCB
  2. PCB会有一个指针,指向程序虚拟内存
  3. 根据虚拟内存的地址所对应的物理内存地址,填充页表,完成映射。

在这里插入图片描述
页表 :页表的作用就是完成虚拟地址到物理地址的转换

下图是解释上面代码例子的虚拟空间问题:子进程创建后,获得父进程一模一样的地址空间,当触发写时拷贝时,才复制资源。这样会节省空间。
在这里插入图片描述

进程地址空间生命周期图解

  1. 程序被读进内存的过程
    在这里插入图片描述

  2. 程序执行的流程
    在这里插入图片描述

为什么要有地址空间呢?

1.为了保护物理内存,页表将各个进程隔离起来了。因为地址空间和页表是OS创建并且维护的,意味着想要使用地址空间和页表映射,必须在OS的监管之下进行访问。因此保证了进程之间的独立性,互不影响。

  1. 因为有地址空间和页表的存在,OS可以实现,对未来的数据进行任意位置的加载,只需根据页表即可找找到杂乱无章的数据。这样物理内存的分配和进程的管理就可以分开进行管理。内存管理模块和进程管理模块就完成了解耦合。

  2. 如果我申请了物理空间,但是我不立马使用,我会造成空间的浪费!但是如果我在虚拟空间上申请,当我没使用时,也没有为我开物理空间 。当我使用时,OS才帮我开辟空间,这样可以保证内存的使用率是100%。

  3. 物理内存上的数据理论上可以在任意位置加载,这会导致物理内存上的所有数据都是乱序的。但是有VA+页表的存在,我们可以方便的直接找到各种数据,在进程的视角,数据是那么的竟然有序!因此,可以将内存分布有序化!

小结

OS的系统是深而庞杂的,此文章只是浅显的谈论了以下内存空间的概念及其分布。更详细的内容,还请读者自行查阅。

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

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

相关文章

微型计算机原理1

一、选择题 1.8086CPU的字长是&#xff08;&#xff09;位。 A. 32 B. 128 C. 64 D. 16 2 间接寻址方式中&#xff0c;操作数在(&#xff09;中。 A. 通用寄存器 B. 内存单元 C. 程序计数器 D.堆栈 3.在循环指令LOOP和串操作指令中,用作计数器的寄存器是() A. AX B. BX C. C…

软件测试/测试开发丨如何利用ChatGPT自动生成测试用例思维导图

点此获取更多相关资料 简介 思维导图是一种用图形方式表示思维和概念之间关系的工具&#xff1a; 有些公司会使用思维导图编写测试用例&#xff0c;这样做的优点是&#xff1a; 1.可视化和结构化。 2.易于理解&#xff0c;提高效率。 而 ChatGPT 是无法直接生成 xmind 格式…

Linux--进程间通信

1.进程间通信 进程间通信的背景&#xff1a; 进程之间是相互独立的&#xff0c;进程由内核数据结构和它所对应的代码和数据&#xff0c;通信成本比较高。 进程间通信目的&#xff1a; 数据传输&#xff1a;一个进程需要将它的数据发送给另一个进程 资源共享&#xff1a;多个进程…

[ Linux Busybox ] flash_eraseall 命令解析

文章目录 相关结构体flash_eraseall 函数实现flash_eraseall 实现流程图 文件路径&#xff1a;busybox-1.20.2/miscutils/flash_eraseall.c 相关结构体 MTD 相关信息结构体 struct mtd_info_user {__u8 type; // MTD 设备类型__u32 flags; // MTD设…

14.序列化和文件的输入/输出 保存对象

14.1 保存对象状态 你已经奏出完美的乐章&#xff0c;现在会想把它储存起来。你可以抓个文房四宝把它记下来&#xff0c;但也可以按下储存按钮(或按下File菜单上的Save)。然后你帮文件命名&#xff0c;并希望这个文件不会让屏幕变成蓝色的画面。 储存状态的选择有很多种&…

App备案-iOS云管理式证书 Distribution Managed 公钥及证书SHA-1指纹的获取方法

​ 根据近日工业和信息化部发布的《工业和信息化部关于开展移动互联网应用程序备案工作的通知》&#xff0c;相信不少要进行IOS平台App备案的朋友遇到了一个问题&#xff0c;就是apple不提供云管理式证书的下载&#xff0c;也就无法获取公钥及证书SHA-1指纹。 ​ 已经上架的应用…

aosp定制android系统

目录 AOSP 准备工作(配置) 确定机型和版本 初始化 git安装 curl安装 同步源码 环境变量 创建aosp目录 指定同步版本 解下来安装编译需要的依赖 编译aosp源码 刷入系统 AOSP 全称 Android Open Source Project 是指Android开源项目&#xff0c;它是由Google主导的…

【有源码】基于uniapp的农场管理小程序springboot基于微信小程序的农场检测系统(源码 调试 lw 开题报告ppt)

&#x1f495;&#x1f495;作者&#xff1a;计算机源码社 &#x1f495;&#x1f495;个人简介&#xff1a;本人七年开发经验&#xff0c;擅长Java、Python、PHP、.NET、微信小程序、爬虫、大数据等&#xff0c;大家有这一块的问题可以一起交流&#xff01; &#x1f495;&…

算法:分治法-力扣题最大子数组和

文章目录 概念应用步骤实现过程-快速排序为例具体实现步骤&#xff1a;代码实现&#xff1a; 力扣-2586统计范围内的元音字符题解 概念 分治法是一种算法思想&#xff0c;其核心思想是将一个大问题分割成若干个小问题来解决。通过对小问题的分别计算&#xff0c;最终得到大问题…

SEO是什么?独立站如何进行SEO优化

创建一个独立网站并不是难事&#xff0c;但要做好独立网站并进行SEO优化以增加自然流量可能是一个不小的挑战。今天&#xff0c;我们将分享一些关于独立网站SEO优化的技巧&#xff0c;并详细探讨如何提升流量。 在本文中&#xff0c;我们将主要关注谷歌SEO&#xff0c;但请不要…

2000-2022年上市公司专利申请、创新绩效数据

2000-2022年上市公司专利申请、创新绩效数据 1、时间&#xff1a;2000-2022年 2、指标&#xff1a;年份、股票代码、股票简称、行业名称、行业代码、省份、城市、区县、行政区划代码、城市代码、区县代码、首次上市年份、上市状态、专利申请总量、发明专利申请总量、实用新型…

Linux--vim

文章目录 Vim的介绍Vim的几种模式命令模式下的基本操作批量化注释Vim的简单配置使用插件 Vim的介绍 Vim是一个强大的文本编辑器&#xff0c;是从vi编辑器发展而来的&#xff0c;在vi编辑器的基础上进行了改进和拓展&#xff0c;具有强大的特性和功能。 Vim是一个自由开源软件&…

技术分享 | app自动化测试(Android)--显式等待机制

WebDriverWait类解析 WebDriverWait 用法代码 Python 版本 WebDriverWait( driver,timeout,poll_frequency0.5,ignored_exceptionsNone) 参数解析&#xff1a; driver&#xff1a;WebDriver 实例对象 timeout: 最长等待时间&#xff0c;单位秒 poll_frequency: 检测的间…

MySQL 8.0 Clone Plugin 详解

文章目录 前言1. 克隆插件安装2. 克隆插件的使用2.1 本地克隆2.2 远程克隆 3. 克隆任务监控4. 克隆插件实现4.1 Init 阶段4.2 File Copy4.3 Page Copy4.4 Redo Copy4.5 Done 5. 克隆插件的限制6. 克隆插件与 Xtrabackup 的异同7. 克隆插件相关参数后记 前言 克隆插件&#xff…

Go uuid库介绍

简介&#xff1a; 在现代软件开发中&#xff0c;全球唯一标识符&#xff08;UUID&#xff09;在许多场景中发挥着重要的作用。UUID是一种128位的唯一标识符&#xff0c;它能够保证在全球范围内不重复。在Go语言中&#xff0c;我们可以使用第三方库github.com/google/uuid来方便…

python 之 集合的相关知识

文章目录 1. 创建集合使用花括号 {}使用 set() 函数 2. 集合的特点3. 集合操作添加元素删除元素 4. 集合运算5. 不可变集合总结 在 Python 中&#xff0c;集合&#xff08;Set&#xff09;是一种无序且不重复的数据集合。它是由一组唯一元素组成的。下面是关于集合的一些基本知…

【云原生】使用nginx反向代理后台多服务器

背景 随着业务发展&#xff0c; 用户访问量激增&#xff0c;单台服务器已经无法满足现有的访问压力&#xff0c;研究后需要将后台服务从原来的单台升级为多台服务器&#xff0c;那么原来的访问方式无法满足&#xff0c;所以引入nginx来代理多台服务器&#xff0c;统一请求入口…

Leetcode-234 回文链表

我的解法&#xff1a;使用栈&#xff0c;定义了len略微复杂&#xff0c;拿链表的后半部分和前半部分比较即可&#xff0c;没必要全部比较 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* List…

369-HI-R-M-0-0-0-E 数字化转型如何改变DCS和SCADA

369-HI-R-M-0-0-0-E 数字化转型如何改变DCS和SCADA 高瞻远瞩的过程制造商正在投资数字化转型&#xff0c;而DCS和SCADA最终将成为这些努力的一部分。因此&#xff0c;它们与所有其他流程制造技术一起发展。DCS和SCADA系统的变化符合自动化金字塔正在进行的转变&#xff0c;它也…

Linux驱动开发——USB设备驱动

目录 一、 USB 协议简介 二、 Linux USB 驱动 三、 USB 设备驱动实例 一、 USB 协议简介 USB(Universal Serial Bus&#xff0c;通用串行总线)正如它的名字一样&#xff0c;是用来连接PC外设的一种通用串行总线&#xff0c;即插即用和易扩展是它最大的特点。所谓即插即用&am…