Linux —— 虚拟进程地址空间

在这里插入图片描述
在这里插入图片描述


🎁个人主页:工藤新一¹

🔍系列专栏:C++面向对象(类和对象篇)

🌟心中的天空之城,终会照亮我前方的路

🎉欢迎大家点赞👍评论📝收藏⭐文章


文章目录

  • 虚拟进程地址空间
    • 一、虚拟地址空间经典布局
    • 二、页表
      • 2.1 核心定义:什么是页表?
      • 2.2 为什么需要页表?
    • 三、虚拟地址空间
      • 3.1 虚拟地址空间是什么?
      • 3.2 如何管理虚拟地址空间?
      • 3.3 为什么要有虚拟地址空间?
    • 四、工业疑问
      • a. 创建进程时,是否可以只创建 PCB/地址空间/页表?
      • b. 创建进程现有task_struct,还是先加载数据/代码
      • c. 如何理解进程挂起?
    • 五、虚拟内存管理

虚拟进程地址空间

虚拟地址空间 是指一个 OS为每个运行中的进程(程序)提供的一个抽象的、独立的、连续的逻辑地址范围。这个空间是 “虚拟的”,这并不意味着物理内存中真的有这么一大块连续的区域,而是通过硬件(MMU,内存管理单元)和 Kernel 的协作,将虚拟地址映射到分散的物理内存页上

在这里插入图片描述


一、虚拟地址空间经典布局

一个进程的典型内存地址空间布局如下图所示,它被划分为多个具有不同权限(读、写、执行)的段(Segments):

从高地址到低地址:

  1. 内核空间(Kernel Space)
    • 通常位于地址空间的最高处(例如,在32位Linux中,0x C000 0000以上)。
    • 存放操作系统内核的代码、数据和数据结构。
    • 所有进程共享同一份内核映射。但这段空间受保护,用户态进程无法直接访问,必须通过系统调用(Syscall)进入内核态才能访问。
  2. (Stack)
    • 向下增长(向低地址方向)。
    • 用于存储局部变量函数参数返回地址等。
    • 每个函数被调用时,会在栈上分配一个新的“栈帧”。
    • 它的增长是自动的,但大小有限(通常默认为几MB),溢出会导致“栈溢出”错误。
  3. 内存映射段(Memory Mapping Segment)
    • 用于映射文件或匿名内存。
    • 动态链接库(如 .so.dll 文件)就加载在这里。
    • 也可以通过 mmap() 系统调用创建,用于大块内存的分配或进程间共享内存。
  4. (Heap)
    • 向上增长(向高地址方向)。
    • 用于动态内存分配。当程序员使用 malloc()new 等申请内存时,内存就从这里分配。
    • 堆的大小只受限于系统可用的虚拟内存总量,管理由程序员负责(分配和释放), improper management leads to memory leaks.
  5. BSS 段(.bss)
    • 存放未初始化的全局变量和静态变量
    • 在程序开始执行前,操作系统会将此段初始化为零。
  6. 数据段(.data)
    • 存放已初始化的全局变量和静态变量
  7. 代码段(文本段)(.text)
    • 存放程序的执行代码(机器指令)。
    • 通常是只读和可执行的,以防止代码被意外修改。
  8. 保留区(Reserved)
    • 通常是最低地址的一段空间(例如 0x00x400000),不允许访问,用于捕捉空指针等错误。

地址区域分布:

在这里插入图片描述


在这里插入图片描述


感受虚拟地址:

fork():一次调用,两次返回

这是理解 fork() 最关键也是最反直觉的一点:

  • 在父进程中,fork() 返回新创建子进程的进程ID(PID)(一个大于0的数)。
  • 在子进程中,fork() 返回 0
  • 如果创建失败(例如系统资源不足),fork() 返回 -1

在这里插入图片描述


进程具有独立性:数据层面上,互不影响;此时就需写时拷贝,实现进程的个性化

在这里插入图片描述

相同地址,获取不同变量值


二、页表

2.1 核心定义:什么是页表?

页表是虚拟内存系统的核心数据结构,是连接 虚拟地址物理地址 的“地图”或“翻译官”;是 Kernel 为每个进程维护的一个映射表,它记录了该进程的虚拟内存页对应到物理内存帧映射关系

简单来说,它的工作就是回答这个问题:

“这个进程看到的虚拟地址 X,实际上在物理内存的哪个地方?”


在这里插入图片描述


在这里插入图片描述


在这里插入图片描述


在这里插入图片描述


在这里插入图片描述

OS 会将进程物理地址隐藏起来,我们只能观测到进程的虚拟地址


解决历史遗留问题:

在这里插入图片描述


2.2 为什么需要页表?

页表是实现虚拟地址空间这一抽象概念的技术基础。没有页表,虚拟内存就无法工作。它的存在是为了:

  1. 实现地址翻译:将程序使用的 虚拟地址转换 为硬件使用的 物理地址
  2. 实施内存保护:通过页表项中的权限位,控制进程对内存的访问(可读?可写?可执行?)。
  3. 支持“换出”到磁盘:通过页表项中的“存在/不存在”位,操作系统可以知道某页是否在物理内存中,如果不在,它的数据存放在硬盘的哪个位置。

三、虚拟地址空间

3.1 虚拟地址空间是什么?

  • **虚拟地址空间本质上就是 OS 给进程画的一张饼! **《大富翁例子》 让进程误以为其独占整个内存的相关资源

画大饼的作用:让每一个进程都认为自己有 4GB的物理内存空间,或者:让每一个进程都认为自己在独占物理内存空间

OS 为每个进程都画了大饼,所以我们也要把这张大饼管理起来


3.2 如何管理虚拟地址空间?

先描述,在组织!

将所有的 虚拟进程地址空间[饼],用链表的方式管理起来;因此,对饼的管理就转化为了对链表的增删查改

虚拟地址空间本质:Kernel当中为进程创建的结构体对象!

在这里插入图片描述


在这里插入图片描述


在这里插入图片描述

在这里插入图片描述


3.3 为什么要有虚拟地址空间?

1. 将无/乱序的物理地址转变为有序的虚拟地址!

  • 对用户(进程)而言:虚拟地址空间是连续且有序的
  • 对系统(操作系统)而言:物理内存[完全随机且不连续]的分配是灵活且混乱的

在这里插入图片描述


2. 地址转化过程中对地址与操作进行合法性判定,进而保护物理内存!

在这里插入图片描述


a. 什么是野指针?

在这里插入图片描述


b. char* str = “hello linux!”; *str = ‘H’;为什么在字符常量区写入就会崩溃?

在这里插入图片描述


在这里插入图片描述


3. 缺页中断 与 按需调页

缺页中断是操作系统 “欺骗” 进程的基础,也是它管理内存的得力工具(画大饼)

在这里插入图片描述


4. 使进程管理与内存管理,进行一定程度的解耦合

在这里插入图片描述


在这里插入图片描述

进程管理 & 内存管理 –——> 直线脱钩


四、工业疑问

a. 创建进程时,是否可以只创建 PCB/地址空间/页表?

核心观点:惰性加载 (Lazy Loading) 与按需调页 (Demand Paging)

问题背后隐藏着一个关键思想:为什么要在进程一开始就把它可能永远用不到的东西全部加载好呢? 这太浪费了….它们遵循 “惰性”原则,只在真正需要时才分配资源。这个过程就是通过 **缺页中断 ** 来实现的


在这里插入图片描述


在这里插入图片描述


b. 创建进程现有task_struct,还是先加载数据/代码

一定先有管理结构task_structmm_struct,空页表[虚物]。滞后加载代码和数据[实物],发生在第一次访问时,由缺页中断机制驱动。并且,加载过程本身也是由这些数据结构指导

在这里插入图片描述


c. 如何理解进程挂起?

在这里插入图片描述


在这里插入图片描述


在这里插入图片描述


在这里插入图片描述


在这里插入图片描述


五、虚拟内存管理

虚拟内存管理是一种内存抽象机制。虚拟内存管理系统的任务,就是将进程使用的这些虚拟地址(Virtual Address)动态地映射到物理内存上的物理地址(Physical Address),或者必要时映射到磁盘上的交换空间(Swap Space)

这个过程主要由计算机的 内存管理单元(MMU) 和操作系统内核共同完成。


描述 Linux 下进程的地址空间的所有的信息的结构体是 mm_struct (内存描述符)。每个进程只有⼀ 个 mm_struct结构,在每个进程的 task_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;/*...*/

  • Virtual Memory

在这里插入图片描述


在这里插入图片描述


进程具有独立性:

  1. 内核数据结构独立!
  2. 加载进内存的代码和数据独立!

在这里插入图片描述


目前,我们对于虚拟地址空间的理解只能做到局部性的逻辑自洽


🌟 各位看官好我是工藤新一¹呀~

🌈 愿各位心中所想,终有所致!
在这里插入图片描述

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

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

相关文章

简单聊一聊js

JavaScript 是一种高级的、解释型的编程语言。它是现代 Web 开发的三大核心基石之一,与 HTML 和 CSS 并列。​HTML​:负责网页的结构和内容​(如标题、段落、图片)。​CSS​:负责网页的样式和布局​(如颜色…

造粒机cad+设计说明书

摘要 随着现代化工业的快速发展,生产出大量的固体废弃物。这些废弃物对环境造成了很大的污染,因此需要采取有效的措施进行处理。机械强压式造粒机就是一种非常有效的处理工具,它可以将废渣、废料、饲料和化肥等材料通过机械强力挤压&#xff…

第五课 C#语言基本元素概览,初始类型,变量与方法,算法简介

熟悉C#语言要求:对构成C#语言的基本元素,随便拿出一个你都认识,对于常见基本元素,都能正确使用它 精通C#语言要求:对于构成C#语言的基本元素,随便拿出一个都会使用,对于常用基本元素&#xff0…

LLM学习:大模型基础——视觉大模型以及autodl使用

1、常见的VLM 在大模型中,VLM 是视觉语言模型(Vision-Language Model)的缩写,是一种多模态、生成式 AI 模型,能够理解和处理视频、图像和文本。 VLM 通过将大语言模型(LLM)与视觉编码器相结合构建而成,使 LLM 具有 “看” 的能力,从而可以处理并提供对提示中的…

Vue—路由配置中设置了meta.title,但页面标题仍然显示为“Vite App“?【让我来看看~】

路由配置中明明设置了meta.title,但是页面标题仍然显示为"Vite App"?这是因为仅仅在路由配置中设置meta.title是不够的,还需要在路由守卫中动态设置页面标题。需要做以下几件事来正确设置页面标题:1.首先更新HTML文件的…

【机器学习】综合实训(二)

项目五 电影评分预测【教学内容】使用 MovieLens 数据集,训练一个模型预测用户对电影的评分。主要有以下几个知识点:(1)数据加载与探索性分析(EDA)。(2)处理稀疏数据(如用…

STM32 UART + DMA + 空闲中断使用中的帧错误(FE)问题及解决方案

STM32 UART + DMA + IDLE中断使用中的帧错误(FE)问题及解决方案 在我调试STM32H7串口空闲中断DMA接受时遇到了一个bug,这个现象发生在系统刚上电时,有个串口由于帧错误FE挂起了中断,之后在HAL_UART_IRQHandler这个全局中断处理函数结束后,所有的中断使能标志位都被清除了,经过…

TDengine 选择函数 BOTTOM() 用户手册

BOTTOM() 函数用户手册 函数定义 BOTTOM(expr, k)功能说明 BOTTOM() 函数统计表/超级表中某列的值最小 k 个非 NULL 值。如果多条数据取值一样,全部取用又会超出 k 条限制时,系统会从相同值中随机选取符合要求的数量返回。 返回值 数据类型: 同应用…

西门子 S7-200 SMART PLC 实现星三角降压启动控制:原理、案例与完整程序

在工业控制场景中,中型异步电机直接启动时会产生远超额定电流的冲击电流(通常为额定电流的 5-7 倍),不仅会影响电网稳定性,还可能对机械设备造成损伤。星三角(Y-Δ)降压启动是解决这一问题的经典…

【Android】View 的基础知识

【Android】View 的基础知识 1. 什么是 View? View 是 Android 中所有UI组件的基础类。它表示屏幕上的一个矩形区域,负责绘制内容和处理用户交互事件。所有的 UI 组件(如按钮、文本框等)都是 View 的子类,而 ViewGroup…

西门子 S7-200 SMART PLC 实现电机点动与连续运行综合控制

在工业生产中,电机控制并非单一模式:调试设备时需要 “按动即转、松开即停” 的点动功能,正常生产时则需要 “一键启动、持续运行” 的连续控制。本文以西门子 S7-200 SMART PLC 为载体,详细讲解电机点动控制原理,并设…

如何解决pip安装报错ModuleNotFoundError: No module named ‘sphinx-rtd-theme’问题

【Python系列Bug修复PyCharm控制台pip install报错】如何解决pip安装报错ModuleNotFoundError: No module named ‘sphinx-rtd-theme’问题 摘要 在使用 PyCharm 开发 Python 项目时,pip install 报错是常见痛点。特别是在构建文档或引入第三方库时,开…

HakcMyVM-Literal

目录信息搜集漏洞利用权限提升信息搜集 主机发现 ┌──(kali㉿kali)-[~] └─$ nmap -sn 192.168.21.0/24 Nmap scan report for 192.168.21.5端口扫描 ┌──(kali㉿kali)-[~] └─$ nmap -sS -sV -O -p- 192.168.21.5 Starting Nmap 7.95 ( https://nmap.org ) a…

0904 类的继承

Part 1.梳理思维导图一.继承中的特殊成员函数1.构造函数父类的构造函数会被继承到子类中&#xff0c;在构造的顺序中&#xff0c;是先构造父类&#xff0c;再构造子类#include <iostream>using namespace std;class Father { public:string name; protected:int *age; pr…

PDF教程|如何把想要的网页保存下来?

前段时间有个小伙伴咨询了小白&#xff1a;领导想要某个网页的整个页面&#xff0c;有没有比较好的方法把它保存下来&#xff1f; 在他找到小白之前&#xff0c;这种事情他已经接到好几次了&#xff0c;每次都是怎么解决的呢&#xff1f;其实很简单&#xff0c;就是打开Word&a…

【bash】命令查看当前目录下文件个数

要用 ls 查看当前目录下的文件个数&#xff0c;可以结合 wc -l 来统计行数&#xff1a; ls -1 | wc -l说明&#xff1a; ls -1&#xff1a;以一行一个文件的方式列出。wc -l&#xff1a;统计行数&#xff0c;也就是文件/目录的数量。 ⚠️ 需要注意&#xff1a; 这个方法会把文…

「日拱一码」081 机器学习——梯度增强特征选择GBFS

目录 什么是梯度增强特征选择&#xff08;GBFS&#xff09; 为什么 GBM 适合做特征选择 GBFS 的一般步骤 代码示例 什么是梯度增强特征选择&#xff08;GBFS&#xff09; GBFS 并非一个像 Lasso 或随机森林那样有严格标准定义的独立算法&#xff0c;而是一种基于梯度提升机…

解构汇编, 万物起源

汇编的诞生汇编全景图核心主干: CPU架构主要分支: 语法和工具共同的地貌: 核心概念延伸: 跨平台 & 跨架构跨平台跨架构总结以 GAS vs. NASM 为例NASM 不支持跨架构 ≠ 无法在ARM架构上的系统安装汇编的诞生 机器语言的困境 早期的程序员直接使用机器语言进行编程机器语言由…

广州旅游网站系统 - 纯静态旅游展示平台

&#x1f31f; 广州旅游网站系统 - 纯静态旅游展示平台观世界才有世界观 - 一个集景区展示、旅游攻略、文化传播于一体的精美旅游网站&#x1f4cb; 项目概述 这是一个专注于广州旅游文化的纯静态网站系统&#xff0c;采用现代化的前端技术栈&#xff0c;为游客提供全方位的广州…

Qt UDP通信学习

Qt UDP通信学习 一、项目概述 本项目基于Qt框架实现了UDP通信功能&#xff0c;支持单播与广播消息收发&#xff0c;展示了UDP套接字的基本用法&#xff0c;适合初学者学习Qt网络模块的实际应用。 二、项目结构 55.pro&#xff1a;Qt工程文件&#xff0c;配置模块与源码文件main…