Linux进程的地址空间

Linux进程的地址空间

1. 前言

在编写程序语言的代码时,打印输出一个变量的地址时,这个地址在内存中是以什么形式存在的?一个地址可以存储两个不同的值吗?

运行以下代码:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
    printf("father is running, pid: %d, ppid: %d\n", getpid(), getppid());


    pid_t id = fork();
    if(id == 0)
    {
        //child
        int cnt = 0;
        while(1)
        {
            printf("I am child process, 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 = 300;
                printf("I am child process, change %d -> %d\n", 100, 300);
            }
        }
    }
    else
    {
        //father
        while(1)
        {
            printf("I am father process, pid: %d, ppid: %d. g_val: %d, &g_val: %p\n", getpid(), getppid(), g_val, &g_val);
            sleep(1);
        }
    }
}

在这里插入图片描述

这个代码打印了父进程和子进程的数据。运行结果发现,在某个时刻g_val的值由100改成300,但它的地址没有改变,也就是说此时同一个“地址”里存储了两个不同的值。

发生这种现象的原因,是**不同的进程由各自的地址空间。**地址空间本质就是内核中的一个结构体对象。

2. 地址空间

每个进程都有自己独立的地址空间独立的页表,页表储存着虚拟地址和物理地址的映射。子进程会拷贝父进程的很多内核数据结构(包括地址空间和页表)。当子进程的数据发生改变时,OS会将被改变的数据进行写时拷贝,存入新的物理地址,同时子进程的页表中对应的物理地址映射发生改变。

在程序中打印的是虚拟地址,但真实的物理地址不一定相同。这是父进程和子进程的变量有相同的“地址”,但变量数据可以不同的原因。

在这里插入图片描述

为什么要有地址空间?

1.将内存空间的无序变成有序,让进程以统一的视角看待物理内存以及自己运行的各个区域。

物理空间中的堆区、栈区、代码区、数据区、共享区、命令行参数和环境变量可能都是无序的,但是通过页表的映射关系可以将无序变为有序管理起来。

2.允许进程管理模块和内存模块进行解耦。

在实际的进程运行中,代码申请的空间短时间内不一定使用。OS可以把代码申请的空间的虚拟地址映射的物理地址先让给别的进程使用,等该进程需要使用的时候再把这块物理地址留给该进程。这种类似于写时拷贝的策略就是解耦,能够提升物理地址的使用效率。

3.拦截非法请求。

进程在运行时,如果遇到非法请求,如代码非法访问了已经释放的空间,在物理地址的层面没有办法阻止这种访问。但在地址空间中,OS会查询页表找对应的地址映射,如果没找到映射,则说明这个访问是非法访问,OS会把这个请求拦截下来(即报错)。

2.1 内核空间

在地址空间的大小一共有4GB,其中[0,3]GB 是用户空间,[3,4]GB是内核空间。我们所写的变量、函数只能够占用用户空间,而系统调用等由操作系统执行的操作都在内核空间中。内核空间的数据有内核级页表来映射到物理地址,与用户级页表不同的是,每一个进程的地址空间有一个用户级页表,但内核级页表是所有进程的内核空间共用一张内核级页表

在这里插入图片描述

3. 页表

3.1 页表介绍

页表中不仅存储着虚拟地址和物理地址的映射,它内部还有各个地址的rwx权限的信息。CPU的cr寄存器中的cr3( 页目录基地址寄存器)存储着页目录的起始地址,所以CPU通过MMU、cr等寄存器,就可以直接访问物理地址。在这里插入图片描述

并且OS在查页表时识别到错误也会有不同判断和处理方式:

1.是不是数据不在物理空间上

引发缺页中断

2.是不是数据需要写时拷贝

进行写时拷贝

3.都不是以上情况,进行异常处理

3.2 内存结构

OS进行内存管理,不是以字节为单位的,而是以内存块为单位的,默认大小4KB。一个内存块叫做页框(页帧)

CPU访问内存时,不是按照实际需要的大小访问,无论是存取指令还是存取数据,所访问的存储单元都趋于聚集在一个较小的连续区域中(4KB),这样的访问方式称为局部性原理。局部性原理能减少写时拷贝的次数,以空间换时间,提高CPU的访问效率。

所以,OS在管理内存时,也是通过一个结构体类型来管理的:

struct page
{

	int flag;//是否被占用,是否是脏页,是否被锁定

	int mode;

}

struct page memory[1048576];//用数组管理。对内存的管理工作转换成了对这个数组的增删查改

3.2 页表的实际结构

页表实际并不是一张表,因为假设在32位系统下,一个虚拟地址占4个字节,地址空间有4GB,如果页表是一张表,页表包含映射关系和状态标记符,总大小至少超过300GB,显然与事实不符。

在32位中,一个虚拟地址有32个比特位,其中高10个比特拿来作为页目录的索引。页目录每个下标的内容存着页表的地址,指向一个页表,页目录一共有1024个索引;中间的10个比特位拿来作为页表的索引,页表里的每个内容存着指向页框的起始地址;低12位比特位从[0,4095]共4096个,拿来作为偏移量在页框内偏移,以此便能找到页框内的每一个内容。

经过这样的变换,页表的最终大小为
1024 ∗ 4 b i t e + 1024 ∗ 2 K B = 2 M B + 4 K B 1024*4bite+1024*2KB=2MB+4KB 10244bite+10242KB=2MB+4KB
在64位的系统中,页表经过更多次的变换,但原理相同。

在这里插入图片描述

虚拟地址&(0xFFF)=页框号

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C#-根据日志等级进行日志的过滤输出

文章速览 概要具体实施创建Log系统动态修改日志等级 坚持记录实属不易&#xff0c;希望友善多金的码友能够随手点一个赞。 共同创建氛围更加良好的开发者社区&#xff01; 谢谢~ 概要 方便后期对软件进行维护&#xff0c;需要在一些关键处添加log日志输出&#xff0c;但时间长…

vulhub——ActiveMQ漏洞

文章目录 一、CVE-2015-5254(反序列化漏洞)二、CVE-2016-3088&#xff08;任意文件写入漏洞&#xff09;2.1 漏洞原理2.2 写入webshell2.3 写入crontab 三、CVE-2022-41678&#xff08;远程代码执行漏洞&#xff09;方法一方法2 四、CVE-2023-46604&#xff08;反序列化命令执行…

HTML+CSS+JS 扩散登录表单动画

效果演示 Code <!DOCTYPE html> <html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,us…

MAIA:多模态自动化可解释智能体的突破

随着人工智能技术的飞速发展&#xff0c;深度学习模型在图像识别、自然语言处理等领域取得了显著成就。然而&#xff0c;这些模型的“黑箱”特性使得其决策过程难以理解&#xff0c;限制了它们的应用范围和可靠性。为了解决这一问题&#xff0c;研究者们提出了多种模型可解释性…

【机器学习】—机器学习和NLP预训练模型探索之旅

目录 一.预训练模型的基本概念 1.BERT模型 2 .GPT模型 二、预训练模型的应用 1.文本分类 使用BERT进行文本分类 2. 问答系统 使用BERT进行问答 三、预训练模型的优化 1.模型压缩 1.1 剪枝 权重剪枝 2.模型量化 2.1 定点量化 使用PyTorch进行定点量化 3. 知识蒸馏…

[emailprotected](7)父子通信,传递元素内容

目录 1&#xff0c;children 属性2&#xff0c;多个属性 普通对象等&#xff0c;可以通过变量直接传递&#xff0c;那类似 vue 中的 slot 插槽&#xff0c;如何传递元素内容&#xff1f; 1&#xff0c;children 属性 实际上&#xff0c;写在自定义组件标签的内部代码&#xf…

【再探】Java—泛型

Java 泛型本质是参数化类型&#xff0c;可以用在类、接口和方法的创建中。 1 “擦除式”泛型 Java的“擦除式”的泛型实现一直受到开发者的诟病。 “擦除式”的实现几乎只需要在Javac编译器上做出改进即可&#xff0c;不要改动字节码、虚拟机&#xff0c;也保证了以前没有使…

k8s pv 一直是release状态

如下图所示&#xff0c;pv 一直是release状态 这个时候大家可能就会想到现在我的 PVC 被删除了&#xff0c;PV 也变成了 Released 状态&#xff0c;那么我重建之前的 PVC 他们不就可以重新绑定了&#xff0c;事实并不会&#xff0c;PVC 只能和 Available 状态的 PV 进行绑定。…

【华为】将eNSP导入CRT,并解决不能敲Tab问题

华为】将eNSP导入CRT&#xff0c;并解决不能敲Tab问题 eNSP导入CRT打开eNSP&#xff0c;新建一个拓扑右键启动查看串口号关联CRT成功界面 SecureCRT连接华为模拟器ensp,Tab键不能补全问题选择Options&#xff08;选项&#xff09;-- Global Options &#xff08;全局选项&#…

ORB-SLAM2从理论到代码实现(六):Tracking程序详解(上)

1. Tracking框架 Tracking线程流程框图&#xff1a; 各流程对应的主要函数 2. Tracking整体流程图 上面这张图把Tracking.cc讲的特别明白。 tracking线程在获取图像数据后&#xff0c;会传给函数GrabImageStereo、GrabImageRGBD或GrabImageMonocular进行预处理&#xff0c;这…

wordpress主题 ACG美化插件v3.4.2支持zibll主题7b2主题美化

独具一格的二次元风格&#xff0c;打造全新的子比美化方向 大部分代码均为CSS、JS做成插件只是为了方便懒人小白站长 后台全功能一览&#xff0c;大部分美化均为网上通用流传&#xff0c;

基于ucos-ii操作系统的生产者消费者-问题

目 录 第1章 题目分析. 1 1.1 生产者线程... 1 1.2 消费者线程... 1 1.3 缓冲区... 1 1.4 进程的同步与互斥... 1 第2章 解决方案. 2 2.1 总体方案... 2 2.2 生产者问题... 2 2.3 消费者问题... 3 2.4 进程问题... 5 第3章 实验结果. 6 3.1 运行结果... 6 3.2 结果分析... 8 第…

用kimi一键绘制《庆余年》人物关系图谱

《庆余年》里面人物关系复杂&#xff0c;如果能画出一个人物关系图谱&#xff0c;可以直观的理解其中人物关系&#xff0c;更好的追剧。 首先&#xff0c;用kimi下载庆余年的分集剧情&#xff0c;常见文章《AI网络爬虫&#xff1a;批量爬取电视猫上面的《庆余年》分集剧情》&am…

【Java面试】三、Redis篇(下)

文章目录 1、抢券场景2、Redis分布式锁3、Redisson实现分布式锁4、Redisson实现的分布式锁是可重入锁5、Redisson实现分布式锁下的主从一致性6、面试 1、抢券场景 正常思路&#xff1a; 代码实现&#xff1a; 比如优惠券数量为1。正常情况下&#xff1a;用户A的请求过来&a…

Centos7.9上安装Oracle 11gR2 RAC 三节点(ASMlib管理asm磁盘)

服务器规划 OS 规格 主机名 IP VIP private IP scanip centos 7.9 1C4G racdb01 192.168.40.165 192.168.183.165 192.168.40.16 192.168.40.200 centos 7.9 1C4G racdb02 192.168.40.175 192.168.183.175 192.168.40.17 192.168.40.200 centos 7.9 1C4G…

目前流行的前端框架有哪些?

目前流行的前端框架有很多&#xff0c;它们可以帮助开发者快速构建高质量的前端应用程序。本文将介绍一些目前比较受欢迎的前端框架&#xff0c;并分析它们的优缺点。 React React 是一个由 Facebook 开发的开源前端JavaScript库&#xff0c;用于构建用户界面&#xff0c;尤其…

基于Vue的图片文件上传与压缩组件的设计与实现

摘要 随着前端技术的发展&#xff0c;系统开发的复杂度不断提升&#xff0c;传统开发方式将整个系统做成整块应用&#xff0c;导致修改和维护成本高昂。组件化开发作为一种解决方案&#xff0c;能够实现单独开发、单独维护&#xff0c;并能灵活组合组件&#xff0c;从而提升开…

OSPF多区域组网实验(华为)

思科设备参考&#xff1a;OSPF多区域组网实验&#xff08;思科&#xff09; 技术简介 OSPF多区域功能通过划分网络为多个逻辑区域来提高网络的可扩展性和管理性能。每个区域内部运行独立的SPF计算&#xff0c;而区域之间通过区域边界路由器进行路由信息交换。这种划分策略适用…

Python 机器学习 基础 之 数据表示与特征工程 【分类变量】的简单说明

Python 机器学习 基础 之 数据表示与特征工程 【分类变量】的简单说明 目录 Python 机器学习 基础 之 数据表示与特征工程 【分类变量】的简单说明 一、简单介绍 二、数据表示与特征工程 数据表示 特征工程 三、分类变量 1、One-Hot编码&#xff08;虚拟变量&#xff09…

【ArcGIS微课1000例】0112:沿线(面)按距离或百分比生成点

文章目录 一、沿线生成点工具介绍二、线状案例三、面状案例一、沿线生成点工具介绍 位置:工具箱→数据管理工具→采样→沿线生成点 摘要:沿线或面以固定间隔或百分比创建点要素。 用法:输入要素的属性将保留在输出要素类中。向输出要素类添加新字段 ORIG_FID,并设置为输…