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.rhkb.cn/news/184442.html

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

相关文章

在MacBook上实现免费的PDF文件编辑

之前我想对PDF文件进行简单处理&#xff08;比如删页面、添空白页、调整页面顺序&#xff09;&#xff0c;要么是开wps会员【花钱贵】&#xff0c;下载&#xff08;盗版&#xff09;Adobe Acrobat【macOS不好下载】&#xff0c;要么用福昕阅览器登陆学生账号&#xff08;学校买…

逆向-文心一言开发者控制台调试

一打开标准的无限debugger 往上一层可以发现是jsvmp&#xff0c;这样替换文件相对来说就不太好搞 根据测试如果卡在debugger就会跳转页面 但是放行debugger就可以正常使用 可以基本确定debugger前后存在计时程序 这个时候就可以考虑对apply做hook劫持无限debugger的函数&#…

Eolink Apikit 版本更新:「数据字典」功能上线、支持 MongoDB 数据库操作、金融行业私有化协议、GitLab 生成 API 文档...

&#x1f389; 新增 搭建自定义接口协议架构&#xff0c;支持快速适配金融行业各类型私有协议的导入、编辑和展示。 数据字典功能上线&#xff0c;支持以数据字典的形式管理参数枚举值&#xff1b; 数据库连接支持 MongoDB 数据库操作&#xff1b; 基于 Apikit 类型导入 API…

Mac下flutter工程配置Gitlab cicd打包(暂时仅限android侧)

写的太粗糙&#xff0c;可能不太适合完全不懂的同学&#xff0c;但是实在没时间&#xff0c;而且也不太会写&#xff0c;权当做一个记录吧&#xff0c;对了还没有搞docker这些&#xff0c;还在持续学习中 1.GitLab Runner&#xff08;打包机&#xff09; 注意:需要有对应的权…

BIM、建筑机器人、隧道工程施工关键技术

一、BIM简介 &#xff08;一&#xff09;BIM概念 BIM&#xff08;Building Information Modeling&#xff09;&#xff0c;建筑信息模型。该技术通过数字化手段&#xff0c;在计算机中建立虚拟建筑&#xff0c;该虚拟建筑提供从单一到完整、包含逻辑关系的建筑信息库。信息库…

遇到不可复现的bug要怎么做?

测试人员遇到不可复现的bug要怎么做&#xff1f; 这是一个很常见的问题&#xff0c;也是一个很棘手的问题。不可复现的bug可能会给测试人员带来很大的困扰和压力&#xff0c;因为它们可能会影响软件的质量和用户的体验&#xff0c;但又很难找到问题的根源和解决方法。因此&…

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

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

深度学习中的数据类型介绍:FP32, FP16, TF32, BF16, Int16, Int8 ...

文章目录 0. 前言1. 数据的存储方式2. 不同数据类型介绍2.1 深度学习中常用的数据类型2.2 BF16 类型的优势2.3 不同数据类型的使用场景 0. 前言 相比于 CPU&#xff0c;GPU 在架构设计时将更多的晶体管用于数据处理&#xff0c;而不是数据缓存和流量控制&#xff0c;因此可以高…

Ansible 自动化运维工具 --- playbook 剧本

文章目录 1. Host inventory ---- 主机清单1.1 简介1.2 inventory文件1.3 Inventory 文件的构成1.3.1 主机与组1.3.2 变量 1.4 inventory 中的常用变量 2. Ansible-playbook剧本2.1 简介2.2 Playbook的结构组成2.3 编写playbook的基本格式与写法2.3.1 基本格式2.3.2 语句的横向…

【Linux】服务器与磁盘补充知识,硬raid操作指南

服务器硬件 cpu 主板 内存 硬盘 网卡 电源 raid卡 风扇 远程管理卡 1.硬盘尺寸: 目前生产环境中主流的两种类型硬盘 3.5寸 和2.5寸硬盘 2.5寸硬盘可以通过使用硬盘托架后适用于3.5寸硬盘的服务器 但是3.5寸没法转换成2.5寸 2.如何在服务器上制作raid 华为服务器为例子做…

Python中通过socketserver库创建服务端

socketserver库是Python的标准库&#xff0c;提供了套接字服务端的框架&#xff0c;通过该框架可以简化服务端的创建流程。 1 socketserver库的导入 通过如图1显示的代码导入socketserver库。 图1 导入socketserver库 2 通过socketserver库创建TCP服务端 通过socketserver库…

二维码智慧门牌管理系统升级解决方案:轻松实现辖区范围门址统计

文章目录 前言一、系统功能与优势 前言 在这个数字化时代&#xff0c;传统的门牌管理系统已经无法满足现代管理的需求。为了满足辖区内门址的统计需求&#xff0c;我们引入了全新的二维码智慧门牌管理系统升级解决方案。这一升级将让您轻松实现辖区范围门址的统计&#xff0c;…

20.7 OpenSSL 套接字SSL加密传输

OpenSSL 中的 SSL 加密是通过 SSL/TLS 协议来实现的。SSL/TLS 是一种安全通信协议&#xff0c;可以保障通信双方之间的通信安全性和数据完整性。在 SSL/TLS 协议中&#xff0c;加密算法是其中最核心的组成部分之一&#xff0c;SSL可以使用各类加密算法进行密钥协商&#xff0c;…

【嵌入式开发工具】STM32+Keil实现软件工程搭建与开发调试

本篇文章介绍了使用Keil来对STM32F103C8芯片进行初始工程搭建&#xff0c;以及开发与工程调试的完整过程&#xff0c;帮助读者能够在实战中体会到Keil这个开发环境的使用方法&#xff0c;了解一个嵌入式工程从无到有的过程&#xff0c;并且具备快速搭建一个全新芯片对应最小软件…

Ubuntu网络IP地址一直显示127.0.0.1

问题描述&#xff1a; 终端输入ip a显示127.0.0.1&#xff0c;原来类似192.168.231.1的地址不见了。 ip a 点击网络配置&#xff08;ubuntu桌面版&#xff09;&#xff0c;发现无线网络模块看不见了 正常情况应该有wired 模块&#xff0c;就是下面标红的 解决方案&#xff1a…

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

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

Flutter的专属Skia引擎解析+用法原理

Skia是一款跨平台的2D图形库&#xff0c;是Google公司开发的&#xff0c;可以用于开发各种应用程序&#xff0c;如浏览器、游戏、移动应用程序等。Skia引擎的主要特点是速度快、可移植性强、占用的内存少、稳定性佳&#xff0c;适用于多种硬件平台。 Skia的目标是提供快速、高…

JavaWeb课程复习资料——idea创建JDBC

1、创建空的Java Project 输入项目名称 空项目 2、引入jar包步骤 依次点击 File -> Project Structure&#xff08;快捷键 Ctrl Alt Shift s&#xff09;&#xff0c;点击Project Structure界面左侧的“Modules”如图&#xff1a; 在 【Dependencies】 标签界面下&…

深度学习中的“钩子“(Hook):基于pytorch实现了简单例子

目录 基本概念一个详细的示例 基于resnet50的一个hook应用例子前向传播示例反向传播示例 基本概念 在深度学习中&#xff0c;“钩子”&#xff08;Hook&#xff09;是一种机制&#xff0c;可以在神经网络的不同层或模块中插入自定义的代码&#xff0c;以便在网络的前向传播或反…

wsl2 ubuntu22.04安装docker

1. 安装 docker 官网的步骤一步一步安装即可 Install Docker Engine on Ubuntu | Docker Docs 2. 安装完毕之后&#xff0c;不出意外的话当你运行docker version或者其他命令的时候你会报如下错误&#xff1a; Cannot connect to the Docker daemon at unix:///var/run/docke…