[ linux-系统 ] 进程地址空间
验证地址空间
父子进程的变量值不同但是地址相同,说明该地址绝对不是物理地址
我们叫这种地址为虚拟地址/线性地址
分析与结论
上述实验表明,父子进程的变量地址相同但内容不同,说明地址为虚拟地址,且父子进程有各自独立的物理地址映射。这验证了虚拟地址的概念,即我们在C/C++中看到的地址是虚拟地址,由操作系统负责将其转化为物理地址。
进程地址空间
让每一个进程都认为自己是独占系统物理内存大小,进程彼此之间不知道,不关心对方存在,从而实现一定程度的隔离
程序地址空间实际上是进程地址空间的子集,是系统级的概念。进程地址空间通过虚拟地址映射实现内存独立性,确保进程间互不干扰。
程序地址空间回顾
看以下C语言代码,感受进程地址空间
1 #include <stdio.h>2 #include <unistd.h>3 #include <stdlib.h>4 5 int gval = 100;6 int unval;7 8 int main() 9 { 10 printf("code addr:%p\n",main);11 printf("gval addr:%p\n",&gval); 12 printf("unval addr:%p\n",&unval);13 14 int *mem = (int*)malloc(10*sizeof(int));15 printf("heap addr:%p\n",mem);16 17 int a,b,c; 18 printf("stack addr:%p\n",&a); 19 printf("stack addr:%p\n",&b); 20 printf("stack addr:%p\n",&c);return 0}
运行结果:
地址整体依次增大,堆区向地址增大方向增长,栈区向地址减少方向增长,验证了堆和栈的挤压式增长方向。
虚拟地址
是进程看到的抽象内存地址,由操作系统和硬件映射到物理内存或磁盘
虚拟进程地址空间本质是一个内核数据结构对象(类似PCB)
进程地址空间通过 mm_struct 结构体来管理各个区域。每个区域的定义如下:
struct mm_struct {long code_start;long code_end;long init_start;long init_end;long uninit_start;long uninit_end;long heap_start;long heap_end;long stack_start;long stack_end;...
}
下面是linux内核中区域划分的源代码:
空间划分的本质:只要告诉我开始和结束即可
理解地址空间的地址
1.地址本质就是一个数字,可以保存在unsigned long
2.空间范围内的地址,可以随便使用,暂时不需要记录它的地址
地址空间和物理内存的关系
我们写了三个程序,将这三个程序运行起来,生成了可执行程序,此时系统存在三个进程,我们有三个task_struct结构体,那么对应的三个进程都有各自的进程地址空间mm_struct,这三个task_struct里面各自会有一个指针指向对应的进程地址空间,我们知道可执行程序运行起来需要将代码和数据加载到内存当中,那么是怎么加载到内存当中的呢?进程将自己的代码和数据首先放在虚拟地址空间的对应的区域,在这其中会有一种表结构,叫做页表,页表的核心工作就是完成虚拟地址到物理地址之间的映射,最终我们的可执行程序的代码和数据可以加载到物理内存的任意位置,因为最终只需要建立代码和数据与物理内存之间的映射关系,就可以通过虚拟地址找到物理内存的对应地址
不同进程的虚拟地址可以完全一样吗?答案是可以完全一样,因为每个进程都有各自的页表,每个进程都是独立的进行通过各自页表中虚拟地址和物理内存的映射关系去找代码和数据
那么不同进程的虚拟地址在页表中映射的物理地址可能会重吗?答案是不会的,如果会重操作系统就挂掉了,有一种可能性会重,但这是我们可以刻意为之,比如创建子进程:
子进程以父进程的PCB为模版创建PCB,子进程也要有自己的进程地址空间,继承父进程的进程地址空间和页表,父子映射到同样的代码段内存区,所以父子代码共享。子进程/父进程不修改变量的时候,数据也是共享的。当要修改/写入时,OS会重新开辟一块目标内存空间,修改页表中的物理地址,即改变页表的映射关系(写时拷贝)
页表
页表标志位:存在位,读写权限位
之前学习C语言时,知道code区域是只读的,char* str = "hello world",*str不能修改
本质是因为这段区域的权限是只读的,对应页表读写权限位是r没有w权限
存在位(isexist):目标内容是否在内存中 (分批操作/挂起等操作)
地址空间mm_struct
每一个可执行程序的代码量都不一样,那么怎样初始化mm_struct这个结构体变量呢?
从可执行程序中来!可执行程序编译的时候,各个区域的大小信息已经有了
指令readelf -S 可以查看各个区域的大小信息
统一框架:mm_struct
的初始化采用固定的框架,确保所有进程都有一致的内存管理基础结构。
动态适配:通过虚拟内存区域和页表的按需分配,内核可以根据程序实际代码量和内存需求进行动态调整,实现高效的内存利用。
进程地址空间的意义
虚拟地址空间+页表可以保护内存
什么是野指针?为什么程序中有野指针就崩溃了?
野指针的地址全是虚拟地址,要么没有映射到物理内存/要么权限不对
进程管理和内存管理在系统层面解耦合了
让进程以统一的视角看待内存
可执行程序的代码和数据可以加载到物理内存的任意位置处,页表+映射可以将"无序"变"有序"
拓展:os 对大文件的分批加载是怎么实现的呢
采用惰性加载的方式
存在 缺页中断 ,重新申请 填写页表
缺页中断:
当一个进程访问虚拟内存中的某一页时,操作系统会先检查该页是否当前已经被加载到物理内存中。如果这一页已经在物理内存中,CPU就可以直接访问它。但是,如果这一页并没有在物理内存中,就会发生缺页中断。
当发生缺页中断时,CPU会暂停当前的执行,并将控制权交给操作系统内核。操作系统内核会首先查找页表,寻找到相关的页面对应的磁盘地址。然后,操作系统会将磁盘上的内容读取到空闲的物理内存页中。
一旦内容被加载到物理内存中,操作系统会更新页表,将该页面的映射关系添加到页表中,然后将控制权交还给进程并重新开始执行。这样,进程可以继续访问所需的内存页面。
整个过程用于解决虚拟内存中的页面不在物理内存中的问题,使得系统看起来好像比它实际拥有的更多内存一样,从而使得多个进程能够共享有限的内存资源,提高内存利用率和系统的整体性能。
就达到分批加载的效果啦
所以 进程 应该是先创建内核数据结构,再执行可执行程序的
全局变量,字符常量具有全局性,在程序运行期间都会有效,因为在地址空间中,随着进程一直存在,全局变量的虚拟地址,会被一直看到
相关文章:

[ linux-系统 ] 进程地址空间
验证地址空间 父子进程的变量值不同但是地址相同,说明该地址绝对不是物理地址 我们叫这种地址为虚拟地址/线性地址 分析与结论 上述实验表明,父子进程的变量地址相同但内容不同,说明地址为虚拟地址,且父子进程有各自独立的物理…...

文件名是 E:\20250512_191204.mp4, EV软件录屏,未保存直接关机损坏, 如何修复?
去github上下载untrunc 工具就能修复 https://github.com/anthwlock/untrunc/releases 如果访问不了 本机的 hosts文件设置 140.82.112.3 github.com 199.232.69.194 github.global.ssl.fastly.net 就能访问了 实在不行,从这里下载,传上去了 https://do…...

Java常见API文档(下)
格式化的时间形式的常用模式对应关系如下: 空参构造创造simdateformate对象,默认格式 练习.按照指定格式展示 package kl002;import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date;public class Date3 {publi…...

DRIVEGPT4: 通过大语言模型实现可解释的端到端自动驾驶
《DriveGPT4: Interpretable End-to-End Autonomous Driving via Large Language Model》 2024年10月发表,来自香港大学、浙江大学、华为和悉尼大学。 多模态大型语言模型(MLLM)已成为研究界关注的一个突出领域,因为它们擅长处理…...
知识图谱(KG)与大语言模型(LLM)
知识图谱(KG)以其结构化的知识表示和推理能力,为大语言模型(LLM)的“幻觉”、知识更新滞后和可解释性不足等问题提供了有力的解决方案。反过来,LLM的强大文本理解和生成能力也为KG的构建、补全、查询和应用…...

构建共有语料库 - Wiki 语料库
中文Wiki语料库主要指的是从中文Wikipedia(中文维基百科)提取的文本数据。维基百科是一个自由的、开放编辑的百科全书项目,覆盖了从科技、历史到文化、艺术等广泛的主题。 对于基于RAG的应用来说,把Wiki语料作为一个公有的语料库…...

苍穹外卖项目中的 WebSocket 实战:实现来单与催单提醒功能
🚀 苍穹外卖项目中的 WebSocket 实战:实现来单与催单提醒功能 在现代 Web 应用中,实时通信成为提升用户体验的关键技术之一。WebSocket 作为一种在单个 TCP 连接上进行全双工通信的协议,被广泛应用于需要实时数据交换的场景&#…...
精益数据分析(59/126):移情阶段的深度博弈——如何避开客户访谈的认知陷阱
精益数据分析(59/126):移情阶段的深度博弈——如何避开客户访谈的认知陷阱 在创业的移情阶段,客户访谈是挖掘真实需求的核心手段,但人类认知偏差往往导致数据失真。今天,我们结合《精益数据分析》的方法论…...

Win10 安装单机版ES(elasticsearch),整合IK分词器和安装Kibana
一. 先查看本机windows是否安装了ES(elasticsearch),检查方法如下: 检查进程 按 Ctrl Shift Esc 组合键打开 “任务管理器”。在 “进程” 选项卡中,查看是否有 elasticsearch 相关进程。如果有,说明系统安装了 ES。 检查端口…...
Ansible模块——主机名设置和用户/用户组管理
设置主机名 ansible.builtin.hostname: name:要设置的主机名 use:更新主机名的方式(默认会自动选择,不指定的话,物理机一般不会有问题,容器可能会有问题,一般是让它默认选择) syst…...

【Redis】List 列表
文章目录 初识列表常用命令lpushlpushxlrangerpushrpushxlpop & rpoplindexlinsertllen阻塞操作 —— blpop & brpop 内部编码应用场景 初识列表 列表类型,用于存储多个字符串。在操作和实现上,类似 C 的双端队列,支持随机访问(O(N)…...

JUC入门(四)
ReadWriteLock 代码示例: package com.yw.rw;import java.util.HashMap; import java.util.Map; import java.util.concurrent.locks.ReentrantReadWriteLock;public class ReadWriteDemo {public static void main(String[] args) {MyCache myCache new MyCache…...

【HarmonyOS 5】鸿蒙mPaaS详解
【HarmonyOS 5】鸿蒙mPaaS详解 一、mPaaS是什么? mPaaS 是 Mobile Platform as a Service 的缩写,即移动开发平台。 蚂蚁移动开发平台mPaaS ,融合了支付宝科技能力,可以为移动应用开发、测试、运营及运维提供云到端的一站式解决…...
多线BGP服务器优化实践与自动化运维方案
背景:企业级网络架构中的线路选择难题 在分布式业务部署场景下,如何通过三网融合BGP服务器实现低延迟、高可用访问?本文以某电商平台流量调度优化为案例,解析动态BGP服务器的实战价值。 技术方案设计 核心架构:采用…...

无法加载文件 E:\Program Files\nodejs\npm.ps1,因为在此系统上禁止运行脚本
遇到“无法加载文件 E:\Program Files\nodejs\npm.ps1,因为在此系统上禁止运行脚本”这类错误,通常是因为你的 PowerShell 执行策略设置为不允许运行脚本。在 Windows 系统中,默认情况下,出于安全考虑,PowerShell 可能会阻止运行未…...

【C++模板与泛型编程】实例化
目录 一、模板实例化的基本概念 1.1 什么是模板实例化? 1.2 实例化的触发条件 1.3 实例化的类型 二、隐式实例化 2.1 隐式实例化的工作原理 2.2 类模板的隐式实例化 2.3 隐式实例化的局限性 三、显式实例化 3.1 显式实例化声明(extern templat…...
TB开拓者策略交易信号闪烁根因及解决方法
TB开拓者策略信号闪烁分析 TB开拓者策略交易信号闪烁根因 TB开拓者策略交易信号闪烁根因分析 信号闪烁是交易策略开发中常见的问题,特别是在TB(TradeBlazer)开拓者等平台上。以下是信号闪烁的主要根因分析: 主要根因 未来函数问题 使用了包含未来信息…...

什么是RDMA?
什么是RDMA? RDMA(RemoteDirect Memory Access)技术全称远程直接内存访问,就是为了解决网络传输中服务器端数据处理的延迟而产生的。它将数据直接从一台计算机的内存传输到另一台计算机,无需双方操作系统的介入。这允许高吞吐、低延迟的网络…...
C++面试3——const关键字的核心概念、典型场景和易错陷阱
const关键字的核心概念、典型场景和易错陷阱 一、const本质:类型系统的守护者 1. 与#define的本质差异 维度#defineconst编译阶段预处理替换编译器类型检查作用域无作用域(全局污染)遵循块作用域调试可见性符号消失保留符号信息类型安全无类…...

ASIC和FPGA,到底应该选择哪个?
ASIC和FPGA各有优缺点。 ASIC针对特定需求,具有高性能、低功耗和低成本(在大规模量产时);但设计周期长、成本高、风险大。FPGA则适合快速原型验证和中小批量应用,开发周期短,灵活性高,适合初创企…...
【C++】嵌套类访问外部类成员
文章目录 C嵌套类访问外部类成员详解:权限、机制与最佳实践一、默认访问权限:并非友元二、访问外部类私有成员的方法1. 声明友元关系2. 通过公有接口访问 三、静态成员 vs. 非静态成员四、实际应用案例:Boost.Asio线程池场景需求实现关键代码…...
mac下载、使用mysql
1.如果对版本没有特别要求,那么直接使用brew install mysql安装即可。 2.使用 brew services start mysql 启动mysql。 3.使用 mysql -u root 登录mysql,这个时候还是不需要密码的 4.退出数据库:exit 5.给root设置一个密码,使用 m…...
java Lombok 对象模版和日志注解
目录 1、依赖: 2、在Idea中确认是否安装Lombok 插件 3、 Lombok常用注解 3.1 Getter 和 Setter 3.2 ToString 3.3 AllArgsConstructor 和 NoArgsConstructor 3.4 Data 3.5 FieldDefaults 4、 Slf4j 日志注解 4.2 日志级别 4.3 设置日志级别 1、依赖:…...

Python学习笔记--使用Django操作mysql
注意:本笔记基于python 3.12,不同版本命令会有些许差别!!! Django 模型 Django 对各种数据库提供了很好的支持,包括:PostgreSQL、MySQL、SQLite、Oracle。 Django 为这些数据库提供了统一的调…...
win11下,启动springboot时,提示端口被占用的处理方式
注:此操作可能存在风险!! 在启动springboot时,提示端口被占用。于是执行 #查看所有的占用的端口 netstat -ano | findStr 8080 结果发现并没有什么进程占据8080端口。再次执行: # 查看系统保留端口 netsh int ipv4…...

计算机视觉设计开发工程师学习路线
以下是一条系统化的计算机视觉(CV)学习路线,从基础到进阶,涵盖理论、工具和实践,适合逐步深入,有需要者记得点赞收藏哦: 相关学习:python深度学习,python代码定制 python…...
AI大模型从0到1记录学习numpy pandas day25
第 3 章 Pandas 3.1 什么是Pandas Pandas 是一个开源的数据分析和数据处理库,它是基于 Python 编程语言的。 Pandas 提供了易于使用的数据结构和数据分析工具,特别适用于处理结构化数据,如表格型数据(类似于Excel表格)…...
Opencv C++写中文(来自Gemini)
基于与Google Gemini交互获取的Opencv在图片上写汉字的实现 sudo apt-get install libfreetype6-dev sudo apt-get install fonts-wqy-zenhei CMakeLists.txt cmake_minimum_required(VERSION 3.10) # Or a more recent versionproject(OpenCVChineseText)set(CMAKE_CXX_STAN…...
下载和导出文件名称乱码问题
只对文件名称进行乱码处理,和文件中的内容无关。 import lombok.SneakyThrows; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.cont…...

STM32实战指南:DHT11温湿度传感器驱动开发与避坑指南
知识点1【DHT11的概述】 1、概述 DHT是一款温湿度一体化的数字传感器(无需AD转换)。 2、驱动方式 通过单片机等微处理器简单的电路连接就能实时采集本地湿度和温度。DHT11与单片机之间采用单总线进行通信,仅需要一个IO口。 相对于单片机…...