【Linux进程篇】Linux内核——程序地址空间的初构

W...Y的主页 😊

代码仓库分享💕 


程序地址空间回顾

我们在讲C语言的时候,大家应该都见过这样的空间布局图:

为了更好的验证不同的数据在内存中的存储位置,下面这段代码我们可以去实验一下:

#include<stdio.h>
#include<stdlib.h>
int g_val = 100;
int g_unval;
int main(int argc, char *argv[], char *env[])
{printf("code addr: %p\n", main);printf("init data addr: %p\n", &g_val);printf("uninit data addr: %p\n", &g_unval);char *heap = (char*)malloc(20);char *heap1 = (char*)malloc(20);char *heap2 = (char*)malloc(20);char *heap3 = (char*)malloc(20);static int c;printf("heap addr: %p\n", heap);printf("heap1 addr: %p\n", heap1);printf("heap2 addr: %p\n", heap2);printf("heap3 addr: %p\n", heap3);printf("stack addr: %p\n", &heap);printf("stack addr: %p\n", &heap1);printf("stack addr: %p\n", &heap2);printf("stack addr: %p\n", &heap3);printf("c addr: %p, c: %d\n", &c, c);for(int i = 0; argv[i]; i++){printf("&argv[%d]=%p\n", i, &argv[i]); }for(int i = 0; env[i]; i++){printf("&env[%d]=%p\n", i, &env[i]);}return 0;
}

 

这就是我们所打印出来的结果,我们可以知道:

1.堆与栈是相对而生的。

2.先有命令行操作符地址再有环境变量的地址 

如果我们想看一下命令行与环境变量存的字符串所在的地址,我们需要稍微修改一下代码:

for(int i = 0; argv[i]; i++)
{printf("argv[%d]=%p\n", i, argv[i]); 
}
for(int i = 0; env[i]; i++)
{printf("env[%d]=%p\n", i, env[i]);
}

 

 这样我们就能看出无论是表还是表指向的项目,都是在栈空间的上面保存着!!!

而我们的static变量的存储位置在未初始变量与初始化数据直接,说明操作系统已经默认把static变量默认成全局变量了,所以他会在我们进程运行期间一直存在不会被销毁。 

那上面的结构图中的地址,是内存的地址吗?我们再来看一段代码:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int g_val = 100;
int g_unval;
int main()
{pid_t id = fork();if (id == 0){int cnt = 0;//子进程while (1){printf("child, pid: %d, ppid: %d, g_val: %d, &g_val: %p\n", getpid(), getppid(), g_val, &g_val);sleep(1);cnt++;if (cnt == 5){g_val = 200;printf("child change g_val: 100->200\n");}}}else{while (1){printf("father, pid: %d, ppid: %d, g_val: %d, &g_val: %p\n", getpid(), getppid(), g_val, &g_val);sleep(1);}}return 0;
}

因为我们知道父子进程中的变量数据是共享的,现在我们有一个全局变量g_val 等于100,当我们让程序运行5秒后在子进程中修改g_val的内容,将100改到200后,我们在进行观察发现子进程中的g_val被修改成200,而父进程的g_val不变。但是父子进程中的g_val的地址却是相同的!!! 

内容不一样地址却一样???综上所述:这个地址绝对不是内存物理地址!!!

这个地址被叫做虚拟地址或者线性地址。 所以我们所使用的地址全都不是物理地址。我们所打印的地址看到的空间排布不是物理内存。

进程地址空间

地址空间(address space)表示任何一个计算机实体所占用的内存大小。比如外设、文件、服务器或者一个网络计算机。地址空间包括物理空间以及虚拟空间。

物理地址 (physical address): 放在寻址总线上的地址。放在寻址总线上,如果是读,电路根据这个地址每位的值就将相应地址的物理内存中的数据放到数据总线中传输。如果是写,电路根据这个地址每位的值就将相应地址的物理内存中放入数据总线上的内容。物理内存是以字节(8位)为单位编址的。

虚拟地址 (virtual address): CPU启动保护模式后,程序运行在虚拟地址空间中。注意,并不是所有的“程序”都是运行在虚拟地址中。CPU在启动的时候是运行在实模式的,内核在初始化页表之前并不使用虚拟地址,而是直接使用物理地址的。

 所以之前说‘程序的地址空间’是不准确的,准确的应该说成 进程地址空间 ,那该如何理解呢?看图:

这就说明在我们的g_val中子进程先将我们父进程的地址空间进行拷贝,而我们的页表如同我们的hash映射一样,将我们的虚拟地址与物理地址进行映射,所以父子进程的g_val的虚拟地址是相同的。

当我们对子进程的值进行修改时,我们操作系统会在物理内存中开辟另一块空间进行储存,而我们的页表的映射关系也会发生改变。即key的值不会改变但value的值会发生改变。

进程地址空间在每一个进程中都会存在一个进程地址空间,在32位操作系统下的范围是[0,4GB]。

在操作系统下管理地址空间就如同管理硬件或PCB,都是创建一个结构体进行管理的其对应的都是数据结构。

那管理进程空间的结构体里面都有说明数据呢?PCB结构体指令中肯定有一个指针指向管理进程空间的结构体中:

 

上图我只截取了一小部分源码,从中我们可以看出有许多划分空间的指针,这些都是为了划分物理内存的虚拟内存指针,还有记录代码、数据、堆、栈等等开始结束的位置。而区域划分的本质就是区域内的各个地址都可以使用 。

我们的地址空间不具备对我们的代码和数据的保存能力,他们都存在物理空间。而给我们一张进程映射表——页表可以将地址空间转换到物理空间中去。

为什么要有地址空间呢?

1.将物理内存从无序变有序,让进程以统一的视角进行管理

2.将进程管理和内存管理进行解耦合

3.内存地址空间+页表是保证内存安全的重要收段

 malloc/new是如何申请空间的呢?

首先我们就要理解new/malloc的堆空间申请开辟后我们不一定是直接使用的。可能是过去1ms甚至1s后我们才去使用的。但是操作系统的主旨是一定要为效率和资源使用率负责的!!!所以我们经常使用的new/malloc本质先不会直接在物理内存中申请开辟空间,而是在虚拟地址中先进行开辟。但是页表中却没有对应物理地址的映射,只有当我们准备进行写入时才会有对应的物理地址和映射关系的出现!!!

这样做的好处是:

1.充分保证内存的使用率。

2.提升new和malloc的性能


以上就是本次的内容,我们已经学习了进程的基本概念,下篇博客我们将学习如何操作进程,请尽情期待!!! 

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

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

相关文章

基于高光谱数据集的创新点实现-高斯核函数卷积神经网络

一、高光谱数据集简介 1.1 数据集简介 数据集链接在这:高光谱数据集(.mat.csv)-科研学术 数据集包含下面三个文件&#xff1a; 文件中包含.mat与.csv,145x145x220, 其实主要使用avirissub.csv文件&#xff0c;在代码上只是将mat文件转成了csv文件。具体avirissub.csv如下&am…

计算机网络-BGP基础概念

一、BGP的基本概念 BGP是一种实现自治系统AS之间的路由可达&#xff0c;并选择最佳路由的矢量性协议。早期发布的三个版本分别是BGP-1&#xff08;RFC1105&#xff09;、BGP-2&#xff08;RFC1163&#xff09;和BGP-3&#xff08;RFC1267&#xff09;&#xff0c;1994年开始使用…

TiDB-从0到1-MVCC

TiDB从0到1系列 TiDB-从0到1-体系结构TiDB-从0到1-分布式存储TiDB-从0到1-分布式事务TiDB-从0到1-MVCC 一、MVCC Multi-Version Concurrency Control 多版本并发控制&#xff0c;其主要解决了读并发的问题。 其维持一个数据的多个版本使读写操作没有冲突。也就是说数据元素X…

虚拟机报错:VMX 进程已提前退出。VMware Workstation 无法连接到虚拟机。

解决报错&#xff1a;VMware Workstation 无法连接到虚拟机。请确保您有权运行该程序、访问该程序使用的所有目录以及访问所有临时文件目录。 VMX 进程已提前退出。 解决方案&#xff1a;右键桌面图标进入VMware Workstation Pro的属性设置&#xff0c;兼容性–勾选“以管理员…

【windows】Total Uninstall:一款功能强大的完全卸载软件

软件介绍 Total Uninstall是一款专业的软件卸载工具&#xff0c;旨在帮助用户彻底地清除计算机上的应用程序&#xff0c;包括与应用程序相关的所有文件和注册表项。以下是Total Uninstall的一些主要功能和特点&#xff1a; 完全卸载&#xff1a;软件可以监视应用程序的安装过程…

【C++题解】1321. 时钟旋转(2)

问题&#xff1a;1321. 时钟旋转&#xff08;2&#xff09; 类型&#xff1a;字符串 题目描述&#xff1a; 时钟从时间&#xff1a;xx:xx&#xff08;xx时xx分&#xff09;&#xff0c;走到时间&#xff1a;xx:xx&#xff08;xx时xx分&#xff09;&#xff0c;时针共旋转了多…

uniapp一些问题解决

1.按钮边框如何去除&#xff1f; 参考博主&#xff1a;微信小程序按钮去不掉边框_微信小程序button去掉边框-CSDN博客文章浏览阅读1k次。最近在学uni-app&#xff0c;顺便自己写个小程序。左上角放了个button&#xff0c;可边框怎么也去不掉…原来微信小程序的按钮要去掉边框要…

新零售数据中台:打造智能商业运营的核心引擎_光点科技

随着数字化转型的浪潮席卷全球&#xff0c;新零售行业正在经历一场前所未有的革新。在这一过程中&#xff0c;“新零售数据中台”逐渐成为企业构建智能商业运营的核心引擎。本文将重点介绍新零售数据中台的概念、其在新零售中的作用&#xff0c;以及如何通过数据中台实现商业价…

基于YOLOV8/YOLOV5的远距离停车场车位检测识别系统

摘要&#xff1a; 在本文中深入探讨了基于YOLOv8/v7/v6/v5的停车位检测系统&#xff0c; 开发远距离停车位检测系统对于提高停车效率具有关键作用。。本系统核心采用YOLOv8技术&#xff0c;并整合了YOLOv7、YOLOv6、YOLOv5算法&#xff0c;以便进行性能指标对比。深入解释了YOL…

【QT环境配置】节约msvc2017灰色不可用问题

1. 问题 msvc2017不可用&#xff0c;2019、2022都同理解决。 2. 解决 第一步&#xff1a;打开控制面板->程序->程序和功能->找到自己安装的vs程序->鼠标右键后出现卸载更改->点击更改。 找到下面组件即可。&#xff08;msvc2019就找msvcv142&#xff09; …

SQL刷题笔记day5

SQL218题目 我的错误代码&#xff1a; select de.dept_no,de.emp_no,s.salary from employees e join dept_emp de on de.emp_no e.emp_no join salaries s on s.emp_no e.emp_no where de.dept_no not in dept_manager.dept_no #not in 好像不能直接这样用 这里报错 正确代…

宝兰德入选“鑫智奖·2024金融数据智能运维创新优秀解决方案”榜单

近日&#xff0c;由金科创新社主办、全球金融专业人士协会支持的“2024 鑫智奖第六届金融数据智能优秀解决方案”评选结果正式公布。凭借卓越的技术实力和方案能力&#xff0c;宝兰德「智能全链路性能监控解决方案」从90个参选方案中脱颖而出&#xff0c;荣誉入选“鑫智奖2024金…

【ArcGISPro】3.1.5下载和安装教程

下载教程 arcgis下载地址&#xff1a;Трекер (rutracker.net) 点击磁力链下载弹出对应的软件进行下载 ArcGISPro3.1新特性 ArcGIS Pro 3.1是ArcGIS Pro的最新版本&#xff0c;它引入了一些新的特性和功能&#xff0c;以提高用户的工作效率和数据分析能力。以下是ArcGIS…

Vue进阶之Vue项目实战(四)

Vue项目实战 出码功能知识介绍渲染器性能调优使用 vue devtools 进行分析使用“渲染”进行分析判断打包构建的产物是否符合预期安装插件使用位置使用过程使用lighthouse分析页面加载情况使用performance分析页面加载情况应用自动化部署与发布CI/CD常见的CI/CD服务出码功能 出码…

香橙派OrangePi AIpro上手笔记——之USB摄像头目标检测方案测试(二)

前期笔记回顾 香橙派OrangePi AIpro上手笔记——之USB摄像头目标检测方案测试&#xff08;一&#xff09; 本章前言 在上一章节&#xff1a;测试笔记&#xff08;一&#xff09;中&#xff0c;我们已经掌握并搭建了板卡的初步调试环境。 接下来&#xff0c;我们将逐步上手官方的…

c 的库函数有哪些

C语言的库函数非常丰富&#xff0c;涵盖了多种功能&#xff0c;为程序员提供了大量的工具来完成各种任务。以下是一些主要的C语言库函数及其分类&#xff1a; 标准输入输出函数&#xff1a; printf()&#xff1a;用于输出格式化的数据到标准输出设备。scanf()&#xff1a;用于…

抠像标签合并到原图,jpg 和 png合并,查看标签是否准确

抠像 原图 和 标签合并&#xff0c;查看抠像是否准确 合并后的图&#xff0c;是带有 羽化 效果的 import osimport cv2 import numpy as npdef apply_mask_with_feathering(original_image_path, mask_image_path):# 读取原图和mask图original_image cv2.imread(original_im…

[Halcon学习笔记]Halcon窗口进行等比例显示图像

目录 需求分析Halcon显示原理显示实现具体实现Halcon代码 需求分析 在使用Halcon加载图像时&#xff0c;点击Halcon的适应窗口&#xff0c;图像都会按照窗口大小对图像进行拉伸后显示&#xff0c;实际项目中&#xff0c;需要等比例显示图像&#xff0c;体现图像原本的尺寸细节…

抖音和快手哪个好?来全面了解一下他们的区别!

快手和抖音虽然是短视频领域的两大主流平台&#xff0c;但是两者也存在本质的区别&#xff0c;从产品定位、用户群体到视频风格、变现模式&#xff0c;它们的特征都不一样。 &#xff08;一&#xff09;两个平台核心区别&#xff1a; 1. 核心用户不一样&#xff1a;抖音以1、…

dubbo复习:(7)使用sentinel对dubbo服务进行限流

一、下载sentinel-dashboard 并启动 java -Dserver.port8080 -Dcsp.sentinel.dashboard.serverlocalhost:8080 -Dproject.namesentinel-dashboard -jar sentinel-dashboard.jar二、在spring boot应用中增加sentinel相关依赖 <dependency><groupId>com.alibaba.csp…