Linux进程的地址空间

news2024/11/20 15:30:50

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)=页框号

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

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

相关文章

云和恩墨海外首秀在吉隆坡召开的2024中国智能科技与文化展览会

作为中马建交50周年官方重点推荐的活动之一&#xff0c;2024中国智能科技与文化展览会&#xff08;第四届&#xff09;于5月20至21日在毗邻吉隆坡双子塔的吉隆坡国际会展中心举办。本次展览会获得马来西亚科学技术创新部、马来西亚通讯部、中国驻马来西亚大使馆和马来西亚中华总…

向郭老师学习研发项目管理

学习研发项目管理思路 通过以下思路来学习研发项目管理&#xff1a; 1、研发项目管理分3级 2、研发项目管理分4类 3、研发项目管理分5大过程组 4、新产品开发项目生命周期分6个阶段 5、研发项目管理分10大知识体系 项目组合、项目集、简单项目3级管理 针对Portfolio组合…

融合基因组序列识别scATAC-seq的细胞类型

利用scATAC-seq技术进行单细胞分析&#xff0c;可以在单细胞分辨率下深入了解基因调控和表观遗传异质性&#xff0c;但由于数据的高维性和极端稀疏性&#xff0c;scATAC-seq的细胞注释仍然具有挑战性。现有的细胞注释方法大多集中在细胞峰矩阵上&#xff0c;没有充分利用潜在的…

列表的创建和删除

目录 使用赋值运算符直接创建列表 创建空列表 创建数值列表 删除列表 自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501\ 对于歌曲列表大家一定很熟悉&#xff0c;在列表中记录着要播放的歌曲名称…

精品UI响应式视频教程知识付费系统源码在线教育网络课程在线点播可二开分销分站功能

这是一款知识付费平台模板&#xff0c;后台可上传本地视频&#xff0c;批量上传视频连接&#xff0c; 视频后台可设计权限观看&#xff0c;免费试看时间时长&#xff0c;会员等级观看&#xff0c;付费观看等功能&#xff0c; 也带软件app权限下载&#xff0c;帮助知识教育和软件…

数据开放最全sql面试合集(leetcode)

关注公众号“大数据领航员"领取PDF版本和大数据面经 https://leetcode-cn.com/problemset/database/ 题目都是leetcode 上了可以点击题目会有相应的链接 由于个人比较喜欢用开窗函数&#xff0c;所以都优先用了开窗 &#xff0c;当然这些并不一定都是最优解&#xff0c…

【C++】多态(多态的原理)

在本篇博客中&#xff0c;作者将会带领你深入理解C中的多态。 声明&#xff01;&#xff01;&#xff01;本代码以及讲解都是在32位机器下进行完成的&#xff0c;64位机器下会有所不同&#xff0c;但大同小异。 一.多态的概念 什么是多态&#xff1f; 多态就是不同的对象去做…

patroni 部分源码阅读

问题1 /usr/local/lib/python3.9/site-packages/patroni/postgresql/init.py 964 contextmanager 965 def get_replication_connection_cursor(self, hostNone, port5432, **kwargs): 966 conn_kwargs self.config.replication.copy() 967 conn_kwar…

【Kubernetes】kubectl详解

陈述式资源管理方法&#xff1a; 1.kubernetes 集群管理集群资源的唯一入口是通过相应的方法调用 apiserver 的接口 2.kubectl 是官方的CLI命令行工具&#xff0c;用于与 apiserver 进行通信&#xff0c;将用户在命令行输入的命令&#xff0c;组织并转化为 apiserver 能识别的…

JavaWeb基础(HTML,CSS,JS)

这些知识用了三四天左右学完&#xff0c;因为是JavaWeb&#xff0c;并不是前端&#xff0c;所以只是够用&#xff0c;不是深入&#xff0c;但是这确实是学校一个学期交的东西&#xff08;JavaWeb课程&#xff09;。 总结一下网页分为三部分&#xff1a;HTML(内容结构),CSS&…

HTML | 在IDEA中配置Tomcat时遇到的一些问题的解决办法

目录 IDEA中没有web文件夹目录 Tomcat在哪里配置服务器 IDEA中没有web文件夹目录 首先说在IDEA中没有web这个文件夹的解决办法 在菜单栏中帮助中点击查找操作搜索添加框架支持&#xff08;因为我的IDEA会出现无法点击这个操作&#xff0c;所以我对该操作添加了快捷键&#xf…

linux系统内存持续飙高的排查方法

目录 前言&#xff1a; 1、查看系统内存的占用情况 2、找出占用内存高的进程 3、解决方法 4、补充&#xff1a;如果物理内存使用完了&#xff0c;会发生的情况 前言&#xff1a; 如果一台服务器内存使用率持续处于一个高峰值&#xff0c;服务器可能会出现响应慢问题。例如s…

03:PostgreSQL逻辑结构(表空间、数据库、模式、表、索引)

环境规划&#xff1a; 操作系统&#xff1a;CentOS 7.9 64bitPostgreSQL 版本&#xff1a;16.x 或 15.x安装用户&#xff1a;postgres软件安装目标路径&#xff1a;/usr/pgsql-<version>数据库数据目录&#xff1a;/pgdata 目录 表空间Tablespace 默认表空间 手动创建…

【Vue】性能优化

使用 key 对于通过循环生成的列表&#xff0c;应给每个列表项一个稳定且唯一的 key&#xff0c;这有利于在列表变动时&#xff0c;尽量少的删除和新增元素。 使用冻结的对象 冻结的对象&#xff08;Object.freeze(obj)&#xff09;不会被响应化&#xff0c;不可变。 使用函…

【贪心算法题目】

1. 柠檬水找零 这一个题目是一个比较简单的模拟算法&#xff0c;只需要根据手里的钱进行找零即可&#xff0c;对于贪心的这一点&#xff0c;主要是在20元钱找零的情况下&#xff0c;此时会出现两种情况&#xff1a;10 5 的组合 和 5 5 5 的组合&#xff0c;根据找零的特点&a…

通过管理系统完成商品属性维护

文章目录 1.数据库表设计1.商品属性表 2.renren-generator生成CRUD1.基本配置检查1.generator.properties2.application.yml 2.启动RenrenGeneratorApplication.java生成CRUD1.启动后访问localhost:812.生成商品属性表的crud 3.将crud代码集成到项目中1.解压&#xff0c;找到ma…

Gittee

前言&#xff1a; 海鸥禁止 git简述 分布式版本控制系统 版本管理 集中式只有一个档案馆 分布式可以每人有一个档案馆&#xff0c;版本合并 协同工作 github&#xff0c;gitlab&#xff0c;gitee是git的托管平台 安装git 略 添加&#xff0c;提交文件 推到远程仓库 常…

vscode安装多版本esp-idf

安装 离线安装 vscode设置 建立一个新的配置文件, 这里面的插件是全新的 安装esp-idf 官网下载espidf 安装这一个 选项默认即可 记住各一个路径, 之后要用到 vscode安装插件 安装以后会进入这一个界面, 也可以CtrlShiftP输入ESP-IDFextension进入 使用espressif 问题 这一个…

微信小程序---小程序文档配置(2)

一、小程序文档配置 1、小程序的目录结构 1.1、目录结构 小程序包含一个描述整体程序的 app 和多个描述各自页面的 page 一个小程序主体部分由三个文件组成&#xff0c;必须放在项目的根目录 比如当前我们的《第一个小程序》项目根目录下就存在这三个文件&#xff1a; 1…

【论文速读】|探索ChatGPT在软件安全应用中的局限性

本次分享论文&#xff1a;Exploring the Limits of ChatGPT in Software Security Applications 基本信息 原文作者&#xff1a;Fangzhou Wu, Qingzhao Zhang, Ati Priya Bajaj, Tiffany Bao, Ning Zhang, Ruoyu "Fish" Wang, Chaowei Xiao 作者单位&#xff1a;威…