【Linux】程序地址空间

程序地址空间

      • 首先引入地址空间的作用
      • 什么是地址空间
      • 为什么要有地址空间

首先引入地址空间的作用

  1 #include <stdio.h>2 #include <unistd.h>3 #include <stdlib.h>4 int g_val = 100;6 int main()7 {8   pid_t id = fork();9   if(id == 0)10   {11     int cnt = 0;12     while(1)13     {14       printf("I am child,pid : %d,ppid : %d,g_val : %d,&g_val : %p\n",getpid(),getppid(),g_val,&g_val);15       cnt++;16       sleep(1);17       if(cnt == 5)18       {19         g_val = 200;20         printf("child chage g_val 100 -> 200 success\n");21       }22     }23   }24   else 25   {26     //father27     while(1)28     {                                                                                                                                                29 30       printf("I am father,pid : %d,ppid : %d,g_val : %d,&g_val : %p\n",getpid(),getppid(),g_val,&g_val);31       sleep(1);32     }33   }34   return 0;35 }

我们发现,但我们子进程修改全局变量g_val的时候,父进程的g_val没有受到影响,但是他们的地址都是一样的,这是为什么呢?

在这里插入图片描述

由此我们知道,这里的地址绝对不是物理内存的地址,而是虚拟地址(线性地址);并且几乎所有语言,如果有地址的概念,这个地址一定不是物理地址,而是虚拟地址。物理地址是由操作系统保管的。以下我们就开始介绍虚拟内存的作用

什么是地址空间

首先基本了解一下地址空间的排布情况

目前我们先不考虑解析这里的共享区在这里插入图片描述

代码实现验证地址空间的排布

  1 #include <stdio.h>2 #include <unistd.h>3 #include <stdlib.h>4 int g_val = 100;5 int g_unval;6 int main(int argc,char *argv[],char *env[])7 {8   //代码区9   printf("code addr:%p\n",main);10   //初始化数据11   printf("init global addr:%p\n",&g_val);12   //未初始化数据13   printf("uninit global addr:%p\n",&g_unval);14   //堆区15   char* heap_mem = (char*)malloc(10);16   char* heap_mem1 = (char*)malloc(10);17   char* heap_mem2 = (char*)malloc(10);18   char* heap_mem3 = (char*)malloc(10);19   printf("heap_mem addr:%p\n",heap_mem);20   printf("heap_mem1 addr:%p\n",heap_mem1);21   printf("heap_mem2 addr:%p\n",heap_mem2);22   printf("heap_mem3 addr:%p\n",heap_mem3);23 24   //栈区25   printf("stack addr:%p\n",&heap_mem);26   printf("stack addr:%p\n",&heap_mem1);27   printf("stack addr:%p\n",&heap_mem2);28   printf("stack addr:%p\n",&heap_mem3);29 //字面常量30   const char *str = "helloworld";31   printf("read only string addr: %p\n", str);32   33   int i,j;34   //命令区                                                                                                35    for(i = 0 ;i < argc; i++)                                                                                                                                             36     {              37         printf("argv[%d]: %p\n", i, argv[i]);38     }        39   40  //环境区41  for(j = 0;env[j];++j)42  {43    printf("env[%d] addr:%p\n",j,&env[j]);44  }45 46   47   48   return 0;49 }

在这里插入图片描述

由此可见我们发现我们输入命令后,命令的地址在我们所执行的代码之后,这说明刚创建好这些变量就有了它自己本身的地址,地址程序结束后才打印,要分清前后

接下来我们来认识什么是地址空间
>

这时我们可以利用虚拟地址加映射机制(页表)来正确的讲地址存入物理内存
虚拟地址:不管哪个编译器,只要看到的地址都是虚拟地址,物理地址是操作系统保管的。
每一行代码都进行了编址。故,程序在编译的时候,每一个字段早已经具有了一个虚拟地址
=什么是映射机制?
映射机制可以将虚拟地址转换到物理地址,如果发现虚拟地址会越界或者错误,则就不会抛出,他起到了关键作用
那么映射机制是怎么判断的呢?
在这里插入图片描述
以上就是所描述的社么是地址空间,简单来说它是存储虚拟地址的。

在这里插入图片描述

地址空间和页表(用户级)是每一个进程都单独有一份的。
只要每一个进程的页表映射的是物理内存的不同区域,就可以做到进程之间不会互相干扰保证进程的独立性。

为什么要有地址空间

  1. 凡是非法的访问或者映射,os都会识别到,并终止你这个进程,有效的保护了物理内存。
    因为地址空间和页表是os创建并维护的,所以凡是使用地址空间和页表的都会在os的监控下来进行范文,这样就间接的保护了物理内存中的所有合法数据和各个进程,以及内核的相关有效数据
  2. 物理内存和进程的管理可以做到解耦合(没关联)。
    当我们申请了物理空间,但是我们不立即使用的时候,就会造成内存空间的浪费;
    针对这一现象,os做出了延迟分配的策略,来提高整机的效率。
    因为地址空间的存在,所有申请的空间都是在地址空间上申请的,物理内存不是被申请到一个字节,当我们真正访问物理地址的时候,才执行内存相关的算法。帮助申请内存,构建页表之间的映射关系,这些都是由os自主完成的
  3. 因为在物理内存中理论上随意加载,也是随意存放的,但是通过地址空间的虚拟地址和页表之间的映射,从进程视角来看所有的内存分布就成有序的了。
    因为有地址空间的存在,每一个进程都认为自己单独有一块4GB(32)空间,并且各个区域是有序的。进而通过页表映射到不同区域,来实现进程的独立性,各个进程是不知道其他进程的存在的

回答问题,为什么地址相同值不同
在这里插入图片描述

发生了写时拷贝!,所以父子进程各自其实在物理内存中,有属于自己的变量空间!只不过在用户层用同一个变量(虚拟地址!)来标识了

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

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

相关文章

【Megatron-DeepSpeed】张量并行工具代码mpu详解(四):张量并行版Embedding层及交叉熵的实现及测试

相关博客 【Megatron-DeepSpeed】张量并行工具代码mpu详解(四)&#xff1a;张量并行版Embedding层及交叉熵的实现及测试 【Megatron-DeepSpeed】张量并行工具代码mpu详解(三)&#xff1a;张量并行层的实现及测试 【Megatron-DeepSpeed】张量并行工具代码mpu详解(一)&#xff1a…

测试老鸟经验总结,Jmeter性能测试-重要指标与性能结果分析(超细)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 Aggregate Report …

【CTF-web】修改请求头(XFF)

题目链接&#xff1a;https://ctf.bugku.com/challenges/detail/id/79.html 随意输入后可以看到需要本地管理员登录&#xff0c;得知这是一道需要修改XFF头的题。 XFF即X-Forwarded-For&#xff0c;该请求标头是一个事实上的用于标识通过代理服务器连接到 web 服务器的客户端的…

【Apollo】Apollo-ros版本架构学习与源码分析

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍Apollo-ros版本架构学习与源码分析。 无专精则不能成&#xff0c;无涉猎则不能通。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&a…

途乐证券-新股行情持续火爆,哪些因素影响首日表现?

全面注册制以来&#xff0c;参加打新的投资者数量全体呈现下降。打新收益下降&#xff0c;破发频出的布景下&#xff0c;投资者打新策略从逢新必打逐步向优选个股改变。 经过很多历史数据&#xff0c;从商场定价、参加者热度以及机构重视度维度揭秘了上市后股价体现优秀的个股具…

时序预测 | Python实现LSTM长短期记忆网络时间序列预测(电力负荷预测)

时序预测 | Python实现LSTM长短期记忆网络时间序列预测(电力负荷预测) 目录 时序预测 | Python实现LSTM长短期记忆网络时间序列预测(电力负荷预测)效果一览基本描述模型结构程序设计参考资料效果一览

记录一下关于word存放代码出现的问题

如下图所示&#xff0c;从 Word 中复制代码并粘贴到其他地方&#xff0c;例如文本编辑器或代码编辑器中&#xff0c;有时会出现额外的连字符或破折号。这是因为 Word 使用了特定的字符编码和格式&#xff0c;而这些字符在代码中可能不被支持或解析为特殊字符。   可见有时从…

拓扑布局和建立小型网络

练习 2.6.1&#xff1a;拓扑布局和建立小型网络 地址表 本实验不包括地址表。 拓扑图 学习目标 正确识别网络中使用的电缆物理连接点对点交换网络验证每个网络的基本连通性 简介&#xff1a; 许多网络问题都可以在网络的物理层解决。因此&#xff0c;必须清楚了解网络连接…

13-把矩阵看作是对系统的描述

探索矩阵乘法&#xff1a;更深刻的理解与应用视角 &#x1f9e9;&#x1f50d; 引言 &#x1f4d6; 在我们进一步探讨矩阵乘法之前&#xff0c;让我们从不同的角度来理解什么是矩阵&#xff0c;以及如何将矩阵视为一个系统。我们之前已经介绍了矩阵的基本概念和运算&#xff…

【QT】 QSS样式表设计一文了解

很高兴在雪易的CSDN遇见你 &#xff0c;给你糖糖 欢迎大家加入雪易社区-CSDN社区云 前言 本文分享QT界面设计中的QSS样式技术&#xff0c;主要从**、**和**方面展开&#xff0c;希望对各位小伙伴有所帮助&#xff01;学会了QSS样式设计&#xff0c;就可以开动你的审美&#…

Zookeeper集群 + Kafka集群

文章目录 Zookeeper集群 Kafka集群一.Zookeeper 概述1.Zookeeper 定义2.Zookeeper 工作机制2.1 Zookeeper 工作机制图示 3.Zookeeper 特点4.Zookeeper 数据结构5.Zookeeper 应用场景5.1 统一命名服务5.2 统一配置管理5.3 统一集群管理5.4 服务器动态上下线5.5 软负载均衡 6.Zo…

JMeter启动时常见的错误

很多小伙伴在学工具这一块时&#xff0c;安装也是很吃力的一个问题&#xff0c;之前记得有说过怎么安装jmeter这个工具。那么你要启动jmeter的时候&#xff0c;一些粉丝就会碰到如下几个问题。 1.解压下载好的jmeter安装&#xff0c;Windows 平台&#xff0c;双击 jmeter/bin …

35岁职业危机?不存在!体能断崖?不担心

概述 90年&#xff0c;硕士毕业&#xff0c;干了快8年的Java开发工作。现年33岁&#xff0c;再过2年就要35岁。 工作这些年&#xff0c;断断续续也看过不少35岁找不到工作&#xff0c;转行&#xff0c;降薪入职的传闻、案例。 35岁&#xff0c;甚至30岁之后&#xff0c;体能…

使用gewe框架进行微信群组管理(一)

友情链接&#xff1a;geweapi.com 点击访问即可。 管理员操作 小提示&#xff1a; 添加、删除、转让多个wxid时仅限于添加/删除管理员&#xff0c;1添加 2删除 3转让 请求URL&#xff1a; http://域名地址/api/group/admin 请求方式&#xff1a; POST 请求头&#xff1a…

Expo项目 使用Native base UI库

装包&#xff1a; yarn add native-base expo install react-native-svg12.1.1 Index.js: import React from react import { View, Text } from react-native import useList from ./useList import { NativeBaseProvider, Button, Box } from native-base import styles f…

Python中搭建IP代理池的妙招

在Python的爬虫世界里&#xff0c;你是否也想搭建一个功能强大的IP代理池&#xff0c;让你的爬虫无忧无虑地畅游各大网站&#xff1f;今天&#xff0c;我就来教你使用Scrapy框架搭建IP代理池&#xff0c;让你的爬虫更加智能、高效&#xff01;跟着我一步一步来&#xff0c;轻松…

NGINX负载均衡及LVS-DR负载均衡集群

目录 LVS-DR原理搭建过程nginx 负载均衡 LVS-DR原理 原理&#xff1a; 1. 当用户向负载均衡调度器&#xff08;Director Server&#xff09;发起请求&#xff0c;调度器将请求发往至内核空间 2. PREROUTING链首先会接收到用户请求&#xff0c;判断目标IP确定是本机IP&#xff…

Android JNI实现锅炉压力显示系统详解

前些天发现了一个蛮有意思的人工智能学习网站,8个字形容一下"通俗易懂&#xff0c;风趣幽默"&#xff0c;感觉非常有意思,忍不住分享一下给大家。 &#x1f449;点击跳转到教程 第一步创建GuoLu.c文件 // // Created by DELL on 2023/8/13. // #include <stdio.h…

vue3使用pinia和pinia-plugin-persist做持久化存储

插件和版本 1、安装依赖 npm i pinia // 安装 pinia npm i pinia-plugin-persist // 安装持久化存储插件2、main.js引入 import App from ./App.vue const app createApp(App)//pinia import { createPinia } from pinia import piniaPersist from pinia-plugin-persist //持…

2023深圳杯A题完整代码模型

已更新深圳杯A题全部版本&#xff0c;文末获取&#xff01; 摘要 现代社会&#xff0c;随着生活方式的变化和工作压力的增大&#xff0c;慢性非传染性疾病日益成为威胁公众健康的主要问题。心脑血管疾病、糖尿病、恶性肿瘤及慢性阻塞性肺病等慢性病的发病率呈现出上升趋势。为…