您的位置:首页 > 新闻 > 资讯 > 高端网站哪个比较好_代码编程入门教学视频_站长工具端口_谈谈你对seo概念的理解

高端网站哪个比较好_代码编程入门教学视频_站长工具端口_谈谈你对seo概念的理解

2025/1/7 11:12:12 来源:https://blog.csdn.net/2302_80190394/article/details/143157431  浏览:    关键词:高端网站哪个比较好_代码编程入门教学视频_站长工具端口_谈谈你对seo概念的理解
高端网站哪个比较好_代码编程入门教学视频_站长工具端口_谈谈你对seo概念的理解

目录

引言

问题导入

进程地址空间

宏观的过程去分析

谈细节

1.进程地址空间究竟是什么

2.页表

3.进程被挂起

4.页表的存在,让进程管理和内存管理相连动

本文核心逻辑


引言


在当今的计算世界中,操作系统是管理计算机硬件和软件资源的关键组件。而在众多操作系统中,Linux以其开源、稳定和高效的特点,成为了广泛使用的系统之一。当我们探讨Linux系统时,程序地址空间无疑是一个核心而神秘的概念。它不仅是进程执行的基础,也是操作系统实现内存保护和高效资源管理的关键机制。本文将带领深入理解Linux程序地址空间的奥秘,从其基本原理到实际应用,揭示这一概念在确保系统稳定运行和优化性能方面的重要作用。  

问题导入

本文通过对进程地址空间的介绍,主要解决以下问题:

1.为什么一个变量会存在两个值

2.以下代码的问题

为什么不加const就会报错,加上const就不会报错。

通过下面的讲解,将会从透过现象看本质的方式去理解它。

进程地址空间

上述的示意图我们可以理解为

需要注意:这并不是真实的物理内存布局,而是虚拟内存/先行内存。

自下到上:代码区、字符常量区、初始化的全局变量、未初始化的全局变量、堆区、栈区。

其中栈区、堆区相对而生。

打印地址观察

可以看到,大体是遵循这张图的(注:该图以32位绘制,实际测试环境为64位)

至于静态的对象:

静态:只不过作用域在某个(函数、结构、、、、)代码块,但是生命周期在全局 

看下一段代码

在父进程中,将g_avl修改为200

结果(32位机器下):

问题暴露:

值不同,但是地址一样

怎么可能,同一个变量,相同的地址,出现了不同的val?

结论:

因此其实所看到的地址并不是真是的物理地址,而是虚拟地址。

我们平时写的C/CPP代码,里面的指针,全部都不是物理地址,而是虚拟地址 \ 线性地址。

宏观的过程去分析

我们都知道,在进程创建时,OS会给我们创建大量的kernel数据结构。

上述画出的地址图,其实就是一种数据结构。进程地址空间:管理进程运行时分配的地址空间的一种数据结构。

接下来的所有问题,都会从这张图中找寻答案(在32位的环境中)。

页表:KV模型,通过虚拟地址可以映射到物理地址

当我们创建子进程时,也会获得一个进程地址空间和页表的数据结构

在最初期,子进程与父进程共享数据和代码

当发生数据修改时,子进程会和内存重新申请一份空间

在这个过程中,虚拟地址并没有发生改变,但是子页表的映射发生变化,将本该映射到11223344的数据映射到了地址为44332211的空间中。

这就是为什么出现虚拟地址相同,但是数据不一致的原因。

谈细节

1.进程地址空间究竟是什么

在32位机器中,内存的物理上限就是4g,为什么呢?

在CPU和内存中,共有32跟总线连接,代表着不同的数据信息,而最多就是2^32(字节)中,因此总共由有4gb

而进程地址空间就是映射的真是的物理内存空间。

拿数据范围是符合划分的呢?

我们说进程地址空间其实是一个结构体,那这个结构体是什么样的呢?在kernel中,存在着这样一个结构体:mm_struct  (mm就是memory)

进程空间存在的意义是什么?

1.由于进程空间的存在,可以让进程对于内存有一个统一的视角去看待。

2.进程地址空间,可以让我们在访问物理内存的时候,增加一个转化的过程,在这个转化的过程中,可以对我们寻求的物理空间做一个审查,一旦访问异常,直接拦截,该请求不会到达物理内存,起到保护物理内存的作用

2.页表

在进程切换时,存在一个叫做cr3的寄存器,可以存储页表的信息。当进程离开cpu时,这些信息转接到pcb中。当cpu重新执行进程时,cr3可以从pcb中读取页表的信息,以便于继续从原来离开的代码块继续执行。

这东西的本质就是硬件的上下文。

一旦访问异常,直接拦截,该请求不会到达物理内存,起到保护物理内存的作用-------这是如何实现的呢?

这主要就是靠页表。

页表除了虚拟地址与物理地址,从还存在一个称为权限的属性栏。

由于内存本身不存在读写属性,这就可以让我们在访问内存的时候,管控内存到底是要读,还是读写都可以。

在进程中,当某段数据申请修改内存的内容时,需要先经过页表,如果页表的权限位只读,那么就禁止修改内存的内容。这就可以很好的保护数据。

这也是为什么常量字符串禁止修改的原因。

3.进程被挂起

linux下的进程管理存在r(运行)s(阻塞、休眠)等状态,但是没有对应的挂起,那进程的挂起在linux中是如何实现的呢?

既然进程可以被挂起,那你怎么知道你的代码在内存还是在磁盘呢?

内存的惰性加载

当我们想要加载一些大型的文件时,往往需要分块去加载这些内容,比如500M的内容,可能内存只会先加载100M。剩下的内容,当你需要的时候,再去内存中加载,这是如何实现的呢?

其实页表还存在一栏,用来检测数据、代码是否被加载到了内存。(目前我们至少知道,页表存在四个栏目)

当虚拟地址存在,想通过虚拟地址去访问物理内存时,发现物理地址不存在,检测栏对应的信息是0(即代码、数据被挂起在磁盘中,没有加载到内存)。内存没有申请,出发缺页中断,此时代码从磁盘加载到内存。

这时候就需要将磁盘中的数据和代码加载到内存,供进程访问使用。

这种惰性加载其实是一种充分节约内存资源的手段。

可见,在进程的执行过程中:先生成内核数据结构,再将数据加载到内存。

4.页表的存在,让进程管理和内存管理相连动

左侧是进程管理,右侧是内存管理。正是由于页表的存在,可以实现内存管理与进程管理的解耦。

使得进程管理模块相对独立。

所有,这时候我们需要对进程有一个重新的认识

进程 = 内核数据结构(pcb(task_struct)   +      mm_struct(进程地址空间)   +   页表) + 代码 + data + 占用的物理空间

进程具有独立性的问题也可以解决了

本文核心逻辑

上面的图就足矣说名问题,同一个变量,地址相同,其实是虚拟地址相同,内容不同其实是被映射到了不同的物理地址!

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com