【Linux篇】探索进程地址空间:计算机背后的虚拟世界

进程地址空间的奥秘:让你理解程序如何在计算机中生存

  • 一. 程序地址空间
    • 1.1 基本概念
    • 1.2 虚拟内存管理
    • 1.3 为什么存在虚拟地址空间
      • 1.3.1 意义
    • 2. 最后

本文将介绍进程地址空间的基本概念与结构,帮助读者理解操作系统如何管理和分配内存。进程地址空间指的是操作系统为每个运行的进程分配的内存区域,包括代码段、数据段、堆区、栈区等。这些区域各自有特定的功能与管理方式。代码段用于存放程序执行指令,数据段用于存放全局变量,堆区用于动态分配内存,而栈区则用于存储函数调用时的局部变量和返回地址。通过了解这些内存区域的作用与分配机制,读者能更好地理解操作系统如何保障多进程运行时的内存安全与隔离性。

💬 欢迎讨论:如果你在学习过程中有任何问题或想法,欢迎在评论区留言,我们一起交流学习。你的支持是我继续创作的动力!
👍 点赞、收藏与分享:觉得这篇文章对你有帮助吗?别忘了点赞、收藏并分享给更多的小伙伴哦!你们的支持是我不断进步的动力!
🚀 分享给更多人:如果你觉得这篇文章对你有帮助,欢迎分享给更多对Linux OS感兴趣的朋友,让我们一起进步!

一. 程序地址空间

1.1 基本概念

虚拟地址空间是指操作系统为每个进程提供的一个独立的内存空间,它与实际物理内存分离。每个进程都拥有自己的虚拟地址空间,操作系统通过内存管理单元(MMU)将虚拟地址映射到物理内存地址,实现了进程间内存的隔离和保护。虚拟地址空间使得每个进程似乎拥有从零开始的连续内存,避免了直接访问物理内存的复杂性,同时提供了更高的灵活性和安全性。

下面来段代码,来验证确实有虚拟地址的存在!

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int g_val = 0;
int main()
{
pid_t id = fork();
if(id < 0){
perror("fork");
return 0;
}
else if(id == 0){ //child,⼦进程肯定先跑完,也就是⼦进程先修改,完成之后,⽗进程再
读取
g_val=100;
printf("child[%d]: %d : %p\n", getpid(), g_val, &g_val);
}else{ //parent
sleep(3);
printf("parent[%d]: %d : %p\n", getpid(), g_val, &g_val);
}
sleep(1);
return 0;
}

输出结果:

child[3046]: 100 : 0x80497e8
parent[3045]: 0 : 0x80497e8

通过现象可以看出,全局变量g_val在父子进程中值不相同,地址却相同。这里的地址就是虚拟地址,为什么值不一样,因为每个进程都会有独立的虚拟地址空间和一套页表(该页表作用:建立虚拟地址与物理地址的映射关系),OS会将虚拟地址转化为物理地址。

图来理解该过程更形象,如下图:

在这里插入图片描述

结论:上⾯的图就⾜矣说明问题,同⼀个变量,地址相同,其实是虚拟地址相同,内容不同其实是被映射到了不同的物理地址!

OS将每个区域进行区域划分。用mm_struct结构体保存相关属性。
上述已经提到了每个进程都有地址空间,那么多的进程地址空间,OS需不需要管理呢???需要的,如何管理:先描述,再组织。

1.2 虚拟内存管理

linux下进程的地址空间的所有的信息的结构体是 mm_struct (内存描述符)。每个进程只有⼀个mm_struct结构,在每个进程的task_struct结构中,有⼀个指向该进程的结构。

  • mm_struct保存的部分属性信息如下:

struct mm_struct
{
//
struct vm_area_struct mmap; / 指向虚拟区间(VMA)链表 /
struct rb_root mm_rb; /
red_black树 /
unsigned long task_size; /具有该结构体的进程的虚拟地址空间的⼤⼩/
/
/
// 代码段、数据段、堆栈段、参数段及环境段的起始和结束地址。
unsigned long start_code, end_code, start_data, end_data;
unsigned long start_brk, brk, start_stack;
unsigned long arg_start, arg_end, env_start, env_end;
/
…*/
}

mm_struct结构是对整个⽤⼾空间的描述。每⼀个进程都会有⾃⼰独⽴的mm_struct,这样每⼀个进程都会有⾃⼰独⽴的地址空间才能互不⼲扰。先来看看由task_struct到mm_struct,进程的地址空间的分布情况:
在这里插入图片描述
因为上述已经说过进程地址空间存在不同的区域,为了达到快速访问的目的,使用vm_area_struct来;连接各个虚拟内存区域(VMA)。

linux内核使⽤ vm_area_struct 结构来表⽰⼀个独⽴的虚拟内存区域(VMA),由于每个不同质的虚拟内存区域功能和内部机制都不同,因此⼀个进程使⽤多个vm_area_struct结构来分别表⽰不同类型的虚拟内存区域。上⾯提到的两种组织⽅式使⽤的就是vm_area_struct结构来连接各个VMA,⽅便进程快速访问。

  • vm_area_struct内核结构如下:

struct vm_area_struct {
unsigned long vm_start; //虚存区起始
unsigned long vm_end; //虚存区结束
struct vm_area_struct *vm_next, *vm_prev; //前后指针
struct rb_node vm_rb; //红⿊树中的位置
unsigned long rb_subtree_gap;
struct mm_struct *vm_mm; //所属的 mm_struct
pgprot_t vm_page_prot;
unsigned long vm_flags; //标志位
struct {
struct rb_node rb;
unsigned long rb_subtree_last;
} shared;
struct list_head anon_vma_chain;
struct anon_vma *anon_vma;
const struct vm_operations_struct *vm_ops; //vma对应的实际操作
unsigned long vm_pgoff; //⽂件映射偏移量
struct file * vm_file; //映射的⽂件
void * vm_private_data; //私有数据
atomic_long_t swap_readahead_info;
#ifndef CONFIG_MMU
struct vm_region vm_region; / NOMMU mapping region */
#endif
#ifdef CONFIG_NUMA
struct mempolicy vm_policy; / NUMA policy for the VMA */
#endif
struct vm_userfaultfd_ctx vm_userfaultfd_ctx;
} __randomize_layout;

将上述结构进行量化,如图:
在这里插入图片描述

1.3 为什么存在虚拟地址空间

  • 内存隔离与安全性:
    虚拟地址空间为每个进程提供独立的内存视图,避免了进程间直接访问彼此内存的风险。这样,即使一个进程出现问题,它的错误也不会影响到其他进程的运行,确保系统的稳定性与安全性。
  • 简化内存管理:
    操作系统通过虚拟地址空间为每个进程提供统一的内存模型,进程无需关心物理内存的具体布局。操作系统可以将虚拟地址映射到不同的物理内存位置,优化内存资源的使用,提高内存管理的灵活性。
  • 支持虚拟内存机制:
    虚拟地址空间使得操作系统能够实现虚拟内存机制,将物理内存的使用扩展到磁盘存储。通过分页和分段等技术,操作系统可以将大于物理内存容量的数据载入内存,只在需要时加载部分内容,从而实现程序运行时的内存“扩展”。
  • 进程迁移与共享:
    在多任务操作系统中,虚拟地址空间使得进程迁移和共享变得容易。虚拟地址映射机制允许进程在不同的物理机器上运行,或者让多个进程共享某一部分内存(如共享库)。

1.3.1 意义

  • 地址空间隔离与安全性
    虚拟地址空间为每个进程提供独立的地址空间,使得不同进程之间的内存互不干扰。这种隔离机制有效防止了进程之间相互访问内存的风险,从而提高了系统的安全性。例如,一个进程不能直接修改另一个进程的内存,避免了内存泄漏或数据破坏的情况。
  • 简化程序开发与管理
    对程序员而言,虚拟地址空间让他们无需关心物理内存的分配与管理。程序可以假定自己拥有完整的内存空间,而操作系统通过地址映射将虚拟地址转换为物理地址。这样,开发者可以集中精力在逻辑和功能开发上,减少了复杂的内存管理问题。
  • 内存共享与优化
    虚拟地址空间还支持进程间的内存共享。例如,当多个进程需要访问相同的共享库时,操作系统可以通过映射同一块物理内存到各自的虚拟地址空间中,从而避免重复加载相同的内容,节省内存资源。此外,虚拟内存还允许操作系统通过分页技术将内存按需分配,优化内存使用。
  • 支持虚拟内存机制
    虚拟地址空间使得虚拟内存的概念成为可能。通过虚拟内存,操作系统能够将物理内存和磁盘空间结合使用,允许程序运行超出实际物理内存大小的应用程序。当物理内存不足时,操作系统会将一些数据暂时移至磁盘(交换区),保证进程继续运行,提升了系统的灵活性和吞吐量。

综上,虚拟地址空间不仅保障了内存的安全、管理简便,还提升了内存利用率和系统性能,是现代操作系统不可或缺的基础设施。

2. 最后

本文主要介绍了进程地址空间的基本概念及其管理方式。进程地址空间是操作系统为每个进程提供的独立内存区域,包括代码段、数据段、堆区和栈区等。通过虚拟内存管理,操作系统实现了进程间内存隔离和保护,确保了系统的安全性与稳定性。文章还阐述了虚拟地址空间的意义,包括内存隔离、简化内存管理、支持虚拟内存机制以及内存共享与优化等。通过这些机制,操作系统能够高效管理内存,提升系统性能和资源利用率,是现代操作系统不可或缺的基础。

路虽远,行则将至;事虽难,做则必成

亲爱的读者们,下一篇文章再会!!! \color{Red}亲爱的读者们,下一篇文章再会!!! 亲爱的读者们,下一篇文章再会!!!

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

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

相关文章

17查询文档的方式

目录 1.鼠标放在你要查询的地方或者选中&#xff0c;按FnF1 2Assistant文档 3帮助菜单界面 1.鼠标放在你要查询的地方或者选中&#xff0c;按FnF1 2Assistant文档 3帮助菜单界面 大家一定要有 查询文档 的意识!! 未来实际开发中,一定会用到很多的第三方库和框架的. 很可能用到的…

壹起航:引领中国工厂迈向全球市场的先锋

在全球化的浪潮中&#xff0c;中国工厂正积极寻求拓展海外市场的新机遇。面对激烈的国际竞争&#xff0c;如何脱颖而出&#xff0c;成为行业翘楚&#xff1f;壹起航凭借其深厚的行业积淀和创新的营销理念&#xff0c;为中国工厂提供了全方位的出海解决方案。 一、构建国际化外…

“数据导航仪”:企业迁移知识库如何赋能精准决策

在全球化与区域经济一体化的浪潮下&#xff0c;企业迁移已成为经济发展的重要现象。 无论是为了拓展市场、降低成本&#xff0c;还是为了寻找更好的政策环境&#xff0c;企业迁移都牵动着无数从业者的心。 然而&#xff0c;面对海量且分散的企业迁移信息&#xff0c;金融机构…

理解激活函数,多个网络层之间如何连接

1. 激活函数如何在两个层之间作用 如果不在两个层之间添加激活函数&#xff0c;模型将无法学习非线性关系&#xff0c;表现出像线性模型一样的局限性。 LeakyReLU(0.2) 是一个激活函数&#xff0c;它的作用是对每一层的输出进行非线性转换。激活函数通常在神经网络中用于增加网…

红帽Linux怎么重置密码

完整流程 ●重启操作系统&#xff0c;进入启动界面 ●然后按进入选择项界面 ●找到linux单词开头的那一行&#xff0c;然后移动到该行末尾&#xff08;方向键移动或者使用键盘上的end&#xff09;&#xff0c;在末尾加入rd.break ●按ctrl x进入rd.break模式 ●在该模式下依次…

pycharm与python版本

python 3.6-3.9 pycharm 2021版本搭配最好 python 3.8 pycharm 2019版本搭配最好 pycharm各版本下载

Java系统集成AI大模型:是否需要训练模型及实现路径

越来越多的Java系统希望通过集成AI大模型能力来提升智能化水平。然而&#xff0c;许多开发者在面对这一任务时&#xff0c;常常会有一个疑问&#xff1a;是否需要训练AI大模型才能实现这一目标&#xff1f;本文将深入探讨这一问题&#xff0c;并提供详细的解决方案。 一、是否…

论文阅读笔记:Denoising Diffusion Implicit Models (3)

0、快速访问 论文阅读笔记&#xff1a;Denoising Diffusion Implicit Models &#xff08;1&#xff09; 论文阅读笔记&#xff1a;Denoising Diffusion Implicit Models &#xff08;2&#xff09; 论文阅读笔记&#xff1a;Denoising Diffusion Implicit Models &#xff08…

【Linux】Linux 系统启动流程详解

1. BIOS/UEFI 阶段 硬件自检&#xff08;POST&#xff09; BIOS/UEFI 执行硬件检查&#xff08;内存、CPU、外设等&#xff09;。若硬件异常&#xff0c;通过蜂鸣码或屏幕提示错误。 选择启动设备 按配置顺序&#xff08;硬盘、U盘、网络等&#xff09;寻找可引导设备。BIOS&a…

C++封装、继承、多态(虚函数)

目录 1、封装 2、继承 继承方式&#xff1a; &#xff08;1&#xff09;公有继承&#xff1b;public &#xff08;2&#xff09;保护继承&#xff1b;protected &#xff08;3&#xff09;私有继承&#xff1b;private 菱形继承&#xff1a; 同名隐藏&#xff1f; 含义…

蓝桥杯冲刺:一维前缀和

系列文章目录 蓝桥杯系列&#xff1a;一维前缀和 文章目录 系列文章目录前言一、暴力的写法&#xff1a;二、一维前缀和的模板&#xff1a; 具体实现&#xff1a; 三、具体例题&#xff1a;求和 1.题目参考&#xff1a;2.以下是具体代码实现&#xff1a; 总结 前言 上次我介绍…

使用UDP建立连接,会存在什么问题?

使用UDP建立连接&#xff0c;会存在可靠性、有序性、连接状态管理等方面的问题&#xff1a; 1、数据传输不可靠&#xff1a; UDP没有确认和重传机制&#xff0c;发送方发送数据后&#xff0c;不会等待接收方的确认消息。这意味着如果数据在传输过程中丢失&#xff0c;发送方不…

YOLOv5配置训练以及华为昇腾910B推理

参考文章&#xff1a; 保姆式yolov5教程&#xff0c;训练你自己的数据集 - 知乎 Windows 10|11下安装mmyolo-0.5.0版本 - 知乎 Ubuntu22.04安装教程&基于华为Ascend AI处理器的om模型atc转换环境安装_ubuntu安装atc工具-CSDN博客嵌入式AI---在华为昇腾推理自己的yolov5目标…

基于yolov11的汽车损伤检测系统python源码+onnx模型+评估指标曲线+精美GUI界面

【算法介绍】 基于YOLOv11的汽车损伤检测系统是一种先进的计算机视觉技术&#xff0c;旨在快速准确地识别汽车的各种损伤类型。该系统利用YOLOv11模型的强大性能&#xff0c;实现了对车辆损伤的精确检测与分类。 该系统能够识别的损伤类型包括裂纹&#xff08;crack&#xff…

[ 3分钟算法 ] | 递归搜索题目 : 合并两个有序链表(递归版)

目录 1. 题目链接&#xff1a; 2. 思路分析&#xff1a; 1. 重复子问题&#xff1f; 2. 具体子问题&#xff1f; 3. 递归出口&#xff1f; 3. 代码实现&#xff1a; 4. 小结&#xff1a; 1. 循环(迭代) vs 递归 2. 递归 vs 深搜 1. 题目链接&#xff1a; 21. 合并…

单元测试原则之——不要模拟值对象 (1)

1. 什么是值对象(Value Objects)? 值对象是指那些不可变且仅通过其属性(数据)来定义的对象。它们通常没有复杂的逻辑或行为,主要用于存储和传递数据。例如: ● 字符串(String) ● 数字(Integer, Double) ● 日期(LocalDate, Instant) ● 自定义的简单数据类(如…

【软件】在Windows和Ubuntu上使用TFTP和NFS

在Windows和Ubuntu上使用TFTP和NFS 零、介绍 最近在玩Linux开发板&#xff0c;在开发的过程中发现需要用到tftp和nfs来帮助传输文件&#xff0c;故此记录如何使用这两种软件。 TFTP&#xff08;Trivial File Transfer Protocol&#xff09; &#xff1a;是一种简化的文件传输…

JS判断变量是否为空的方法

在 JavaScript 中&#xff0c;判断变量是否为空需要根据不同的数据类型和具体需求来处理。以下是常见场景的解决方案&#xff1a; 1. 基础判断&#xff1a;null 或 undefined javascript if (value null || value undefined) {// 变量为空 } 或简写为&#xff1a; javasc…

Linux更换挂载nfs迁移数据流程

当前&#xff1a;原nfs&#xff08;10.16.2.1:/myData&#xff09;挂载在/myData&#xff0c;新的nfs&#xff08;10.16.2.2:/myData&#xff09;未挂载 目标&#xff1a;把旧nfs的数据迁移到新的nfs上&#xff0c;并把新nfs挂载到/myData 步骤&#xff1a; 1、新nfs挂载到一…

深入解析音频:格式、同步及封装容器

物理音频和数字音频 物理音频 定义&#xff1a;物理音频就是声音在自然界中的物理表现形式&#xff0c;本质上是一种机械波&#xff0c;通过空气或其他介质传播。例如&#xff0c;当我们说话、乐器演奏或物体碰撞时&#xff0c;都会产生振动&#xff0c;这些振动会引起周围介…