地址空间 (Address Space)

news2024/11/24 4:32:07

在这里插入图片描述

文章目录:

  • 程序地址空间
  • 进程地址空间

程序地址空间

什么是地址空间:地址空间是内存中可供程序或进程使用的有效地址的范围。也就是说,它是程序或进程可以访问的内存。内存可以是物理的、也可以是虚拟的,用于执行指令和存储数据。

在之前 c/c++ 的学习中,我们所知道的空间布局图如下:
在这里插入图片描述
我们可以在 Linux 操作系统中,对上面的空间布局图进行验证:

// 验证程序地址空间的分布
#include<stdio.h>
#include<stdlib.h>

int un_g_val;
int g_val=10;

int main(int argc,char *argv[],char *env[])
{
    printf("code addr           :%p\n",main);
    printf("init global addr    :%p\n",&g_val);
    printf("uninit global addr  :%p\n",&un_g_val);
    char *m1 = (char*)malloc(10);
    printf("heap addr           :%p\n",m1);
    printf("stack addr          :%p\n",&m1);
    
    for(int i=0;i<argc;++i)
    {
         printf("argv addr           :%p\n",argv[i]);
    }
    for(int i=0;env[i];++i)
    {
         printf("env addr            :%p\n",env[i]);
    }
    return 0;
}

测试结果如下,符合上图的分布:

在这里插入图片描述

下面来看一段代码及其运行结果:fork() 创建子进程,子进程打印两次之后更改全局变量的值。

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>

int g_val = 10;

int main()
{
    pid_t id = fork();
    if(id == 0)
    {
        // child process
        int count = 0;
        while(1)
        {
            printf("I am a child process! PID : %d,PPID : %d,g_val = %d,&g_val = %p\n",getpid(),getppid(),g_val,&g_val);
            sleep(1);
            count++;
            if(count == 2)
            {
                g_val = 7;
                printf("I am a child process,g_val has changed!\n");
            }
        }       
    }
    else 
    {
        // parent process
        while(1)
        {
            printf("I am a parent process! PID : %d,PPID : %d,g_val = %d,&g_val = %p\n",getpid(),getppid(),g_val,&g_val);
            sleep(1);
        }
    }
    return 0;
}

运行结果:

在这里插入图片描述

🎯根据上述运行结果,我们发现,在子进程还没有修改全局数据的时候,输出的变量和地址是一样的,因为子进程按照父进程为模板,父子进程并没有对变量进行任何修改。但是当子进程将代码中的全局变量更改之后,我们发现,父子进程,输出的地址一样,但是变量的内容却不一样。因此我们得出以下结论:

  • 变量的内容不一样,说明父子进程输出的变量绝对不是同一个变量。
  • 但是变量对应的地址确实一样的,说明,该地址绝对不是物理地址!在 Linux 操作系统下,我们将此地址叫做 虚拟地址
  • 我们之前在 c/c++ 中所看到的地址,全部都是虚拟地址。物理地址,我们是看不到的,由 OS 同一进行管理。

🎭 OS 需要将 虚拟地址 转化为 物理地址。

进程地址空间

地址空间是计算机内存中的一个空间。进程地址空间是指在内存中为进程分配的空间。每个进程都有一个地址空间。地址空间有两种类型:物理地址空间、虚拟地址空间。

所以之前所说的程序地址空间是不准确的,准确来说应该称为进程地址空间,进程地址空间是内存中的一种内核数据结构。Linux 中由内存描述符(mm_struct)来描述有关进程地址空间的所有信息。

mm_struct 定义在 <linux/sched.h> 下:

206 struct mm_struct {
207     struct vm_area_struct * mmap;
208     rb_root_t mm_rb;
209     struct vm_area_struct * mmap_cache;
210     pgd_t * pgd;
211     atomic_t mm_users;
212     atomic_t mm_count;
213     int map_count;
214     struct rw_semaphore mmap_sem;
215     spinlock_t page_table_lock;
216 
217     struct list_head mmlist;
221 
222     unsigned long start_code, end_code, start_data, end_data;
223     unsigned long start_brk, brk, start_stack;
224     unsigned long arg_start, arg_end, env_start, env_end;
225     unsigned long rss, total_vm, locked_vm;
226     unsigned long def_flags;
227     unsigned long cpu_vm_mask;
228     unsigned long swap_address;
229 
230     unsigned dumpable:1;
231 
232     /* Architecture-specific MM context */
233     mm_context_t context;
234 };

内存区域:线性地址的间隔,其特征是初始线性地址、长度和一些访问权限。
Linux 操作系统用 vm_area_struct 来管理内存区域。

vm_area_struct 被定义在 <linux/mm.h> 中:

 44 struct vm_area_struct {
 45     struct mm_struct * vm_mm;
 46     unsigned long vm_start;
 47     unsigned long vm_end;
 49 
 50     /* linked list of VM areas per task, sorted by address */
 51     struct vm_area_struct *vm_next;
 52 
 53     pgprot_t vm_page_prot;
 54     unsigned long vm_flags;
 55 
 56     rb_node_t vm_rb;
 57 
 63     struct vm_area_struct *vm_next_share;
 64     struct vm_area_struct **vm_pprev_share;
 65 
 66     /* Function pointers to deal with this struct. */
 67     struct vm_operations_struct * vm_ops;
 68 
 69     /* Information about our backing store: */
 70     unsigned long vm_pgoff;
 72     struct file * vm_file;
 73     unsigned long vm_raend;
 74     void * vm_private_data;
 75 };

在这里插入图片描述
当一个进程被创建时,其对应的进程控制块(task_struct)和进程地址空间(mm_struct)也随之被创建。操作系统可以通过进程的 task_struct 来找进程对应的 mm_struct 。

🎭 如下所示,父进程创建了子进程后,父子进程都有属于自己的进程控制块,父进程和子进程中的进程地址空间中的虚拟地址通过页表映射到物理内存中:

在这里插入图片描述
通过此图我们就可以解释上面代码中的问题,当子进程被创建时,子进程和父进程的数据和代码共享。父子进程的代码和数据通过各自的页表映射到物理内存的同一块区域。因此,当子进程和父进程没有对数据进行修改的时候,它们的数据是一样的,是同一份。但是当子进程更改了全局数据,那么就会在内存中某一空间存储一个更改的新数据,并且更改子进程页表中 g_val 的虚拟地址所映射的物理地址。

虚拟地址存在的意义:

  • 虚拟内存将主存看作是在磁盘地址空间上的高速缓存,主存中只报保存活动区域并根据需要在磁盘和主存之间来回传送数据。
  • 虚拟地址允许我们有内存保护,每个进程的地址空间不被其它程序破坏。
  • 允许通过磁盘来扩展物理内存的使用。
  • 为进程提供的一致的地址空间简化了内存管理。

对于虚拟地址和物理地址的关系,就简单介绍这些了。

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

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

相关文章

nginx开启Gzip压缩,Vue性能优化之使用gzip压缩打包

一、前言不管是vue项目还是react项目在使用webpack打包之后都会生成一个动辄一两兆甚至更大的js文件&#xff0c;在某些情况下严重影响项目性能&#xff0c;打开页面的时候白屏时间会很长&#xff0c;本文将介绍如何使用gzip压缩打包&#xff0c;主要是nginx部署的配置&#xf…

hadoop环境新手安装教程

1、资源准备&#xff1a; &#xff08;1&#xff09;jdk安装包&#xff1a;我的是1.8.0_202 &#xff08;2&#xff09;hadoop安装包&#xff1a;我的是hadoop-3.3.1 注意这里不要下载成下面这个安装包了&#xff0c;我就一开始下载错了 错误示例&#xff1a; 2、主机网络相…

天荒地老修仙功-第六部:Spring Cloud中7中负载均衡策略

文章目录前言Ribbon介绍负载均衡设置七种负载均衡策略1、轮询策略2、权重策略3、随机策略4、最小链接数策略5、重试策略6、可用性敏感策略7、区域敏感策略总结前言 负载均衡器通常有两种实现手段&#xff0c;一种是服务端负载均衡器&#xff0c;另一种是客户端负载均衡器&…

线程池的常见知识点总结

文章目录1. 什么是线程池2. 为什么使用线程池3. 线程的作用4. 如何创建线程池5. 线程持底层是如何实现复用的6. 手写一个简易的线程池7. ThreadPoolExecutor构造函数原理8. 线程池创建的线程会一直运行下去吗&#xff1f;9. 线程池队列满了任务会丢失吗&#xff1f;分析情况有界…

xilinx srio ip学习笔记之axistream接口

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 xilinx srio ip学习笔记之axistream接口前言接口转化前言 srio 的IQ接口都是基于axistream的&#xff0c;以前没怎么用过axistream的接口&#xff0c;或者说没怎么用过复杂条…

C语言--数据的存储2

目录前言练习有符号类型与无符号类型char类型的取值范围有符号char无符号char有符号与无符号类型混合运算有符号无符号类型形成的bugchar类型取值范围应用浮点型在内存中的存储浮点数的存储浮点数存储规则浮点数取出规则前言 上篇文章我们讲解了数据类型&#xff0c;类型的基本…

招标采购流程的电子招标采购,是管理复杂供应链和多层供应商的高效方式。

负载均衡&#xff08;Load Balance&#xff09; 由于目前现有网络的各个核心部分随着业务量的提高&#xff0c;访问量和数据流量的快速增长&#xff0c;其处理能力和计算强度也相应地增大&#xff0c;使得单一的服务器设备根本无法承担。在此情况下&#xff0c;如果扔掉现有设…

(二)、安装uview及配置项中的易错项【uniapp+uinicloud多用户社区博客实战项目(完整开发文档-从零到完整项目)】

1.打开hbuilder软件&#xff0c;新建uniapp项目 2.关联unicloud服务空间 2.1 项目文件夹鼠标右键&#xff0c;打开uicloud web控制台 2.2 注册HBuilder 账号 dcloud账号注册链接 2.3 新建服务空间 大约等待2分钟&#xff0c;服务空间初始化完毕&#xff01;就可以使用了。 …

每天10个前端小知识 【Day 15】

前端面试基础知识题 1.两个同级的相邻元素之间&#xff0c;有看不见的空白间隔&#xff0c;是什么原因引起的&#xff1f;有什么解决办法&#xff1f; 行框的排列会受到中间空白&#xff08;回车空格&#xff09;等的影响&#xff0c;因为空格也属于字符,这些空白也会被应用样…

Mob研究院联合明源地产研究院发布《2022年商业地产发展白皮书》

Mob研究院近日联合明源地产研究院共同发布《2022年商业地产发展白皮书》&#xff0c;报告从行业现状、企业概况、新兴业态和未来展望四个方面对商业地产行业进行了全景扫描&#xff0c;深入分析了由于疫情的影响以及消费人群和习惯的改变&#xff0c;2022年商业地产行业中所发生…

Ubuntu 22.04安装搜狗输入法

Ubuntu 22.04安装搜狗输入法 ubtuntu 22.04安装搜狗输入法 1. 添加中文语言支持2. 安装fcitx输入法框架3. 设置fcitx为系统输入法4. 设置fcitx开机启动&#xff0c;并卸载ibus输入法框架5. 安装搜狗输入法6. 重启电脑&#xff0c;调出搜狗输入法 1. 添加中文语言支持 Setti…

营销自动化的CRM系统能够解决哪些问题

CRM客户管理系统营销自动化的范围远远超出了人们的认知。许多人认为它只是自动化完成重复和乏味的任务来减少营销人员的工作量。虽然这确实占了很大一部分&#xff0c;但它真正的价值在于提高潜客转化&#xff0c;增加业务收入。那么&#xff0c;什么是CRM系统营销自动化&#…

【23种设计模式】行为型模式详细介绍(上)

前言 本文为 【23种设计模式】行为型模式 相关内容介绍&#xff0c;下边将对访问者模式&#xff0c;模板模式&#xff0c;策略模式&#xff0c;状态模式&#xff0c;观察者模式&#xff0c;备忘录模式&#xff0c;中介者模式&#xff0c;迭代器模式&#xff0c;解释器模式&…

实现一个简单的Database10(译文)

GreatSQL社区原创内容未经授权不得随意使用&#xff0c;转载请联系小编并注明来源。GreatSQL是MySQL的国产分支版本&#xff0c;使用上与MySQL一致。作者&#xff1a; 花家舍文章来源&#xff1a;GreatSQL社区原创 前文回顾 实现一个简单的Database系列 译注&#xff1a;csta…

测试用例设计工作中的应用

1. 等价类划分 常见的软件测试面试题划分等价类: 等价类是指某个输入域的子集合.在该子集合中,各个输入数据对于揭露程序中的错误都是等效的.并合理地假定:测试某等价类的代表值就等于对这一类其它值的测试.因此,可以把全部输入数据合理划分为假设干等价类,在每一个等价类中取一…

水溶性花青素连接剂1617497-19-4,diSulfo-Cyanine5 alkyne,二磺酸花青素Cy5炔基

一、理论分析&#xff1a;中文名&#xff1a;二磺酸-花青素Cy5-炔基英文名&#xff1a;diSulfo-Cy5 alkyne&#xff0c;diSulfo-Cyanine5 alkyne&#xff0c;diSulfo Cyanine5 alkyneCAS号&#xff1a;1617497-19-4化学式&#xff1a;C35H40N3NaO7S2分子量&#xff1a;701.8二、…

TypeScript基本教程

TS是JS的超集&#xff0c;所以JS基础的类型都包含在内 起步安装 npm install typescript -g运行tsc 文件名 基础类型 Boolean、Number、String、null、undefined 以及 ES6 的 Symbol 和 ES10 的 BigInt。 1 字符串类型 字符串是使用string定义的 let a: string 123 //普…

富媒体数据管理解决方案:简化、优化、自动化

富媒体数据管理解决方案&#xff1a;简化、优化、自动化 适用于富媒体的 NetApp 解决方案有助于简化和降低数据管理成本&#xff0c;优化全球媒体工作流并自动执行媒体资产管理。这将有助于减轻您的负担。 为什么选择 NetApp 的富媒体数据管理解决方案&#xff1f; 成本更低…

C语言( 缓冲区和重定向)

一.缓冲输入&#xff0c;无缓存输入 while((chgetchar()) ! #) putchar(ch); 这里getchar(),putchar()每次只处理一个字符&#xff08;这里只是知道就好了&#xff09;&#xff0c;而我们使用while循环&#xff0c;当读到#字符时停止 而看到输出例子&#xff0c;第一行我们输入…

适用于iOS的远程桌面软件

全球远程桌面软件市场最近达到19.2亿美元&#xff0c;表明使用任意设备实现随处远程控制越来越受欢迎。 近年来&#xff0c;企业的运营方式发生了重大改变&#xff0c;远程桌面软件已成为广泛使用的解决方案。Splashtop 是目前最好用的远程桌面工具之一&#xff0c;安全可靠且…