Linux【进程地址空间】

news2024/12/18 17:31:52

进程地址空间

    • 📖1. 地址空间概念
    • 📖2. 写时拷贝
    • 📖3. 虚拟地址空间的优点

📖1. 地址空间概念

在学习C/C++内存管理时,我们可能见过这样一幅图:

image-20221025201246892

但是我们可能不是很理解它,首先有一个问题:这段空间指的是内存吗?

首先,这段空间它并不是内存,它是操作系统提供的一个易用的物理内存抽象,叫做地址空间. 通过这个物理内存抽象,我们可以让每个进程都认为它有这么一段供自己使用的空间,但是它并不是真实的物理空间,那么真实的物理空间在哪里呢?

我们知道,数据实际上肯定是存储在物理内存中的,所以当我们拿到虚拟地址的时候,需要将它转换为物理地址供进程使用,所以,我们需要通过页表来完成从虚拟地址到物理地址的映射,当我们拿到一个虚拟地址时,便可以通过页表和MMU中的地址翻译硬件将它转化为实际的物理地址.

image-20221025220351947

对于上面的地址空间的布局图,我们可以写出代码来验证一下:

image-20221025222040322

运行结果:

image-20221025221953009

可以看出,堆和栈之间是有一段比较大的地址镂空的.

再接着,我们通过代码来观察一个现象:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>

int g_val = 10;

int main()
{
  pid_t id = fork();

  if(id == 0)
  {
    int flag = 0;

    while(1)
    {

      printf("我是子进程,%d, ppid:%d, g_val:%d, &g_val:%p\n", getpid(), getppid(), g_val, &g_val);

      sleep(1);
      flag++;

      if(flag == 5)
      {
        g_val = 20;
        printf("我是子进程,g_val已经被我修改\n");
      }
    }
  }
  else
  {
    while(1)
    {
      printf("我是父进程,%d, ppid:%d, g_val:%d, &g_val:%p\n", getpid(), getppid(), g_val, &g_val);
      sleep(1);
    }
  }

  return 0;
}

运行结果如下:

image-20221025223719667

我们可以看到,在未修改g_val之前,父进程和子进程的g_val值相同,并且地址也相同,那么我们可能会想,子进程与父进程用的是同一地址处的同一份数据,但是当g_val的值被子进程修改之后,我们惊奇的发现:父进程和子进程中的g_val地址是相同的,但是值却不一样,这怎么可能?

所以,由这里我们就能看出,我们看到的地址,并不是真实的,它是虚拟地址,那么,接下来,我们就一起来看一看进程地址空间:

每一个进程在启动的时候,操作系统都会给它创建一个地址空间,该地址空间就是虚拟地址空间.

Linux的虚拟地址空间,对于32位处理器,虚拟内存空间为4G,每个进程都认为自己拥有4G的空间,实际上,在虚拟内存对应的物理内存上,可能只对应一点点的物理内存.

进程得到的这4G的虚拟内存是一个连续的地址空间(这也只是进程认为),而实际上,它通常是被分隔成多个物理碎片,还有一部分存储在外部磁盘上,在需要时进行数据交换.

这也是内存管理中的虚拟内存技术:OS为每个程序分配地址(逻辑地址),每个地址由多个页组成,这些页可以不在真正的物理地址中,而是被映射到了物理地址中,也不需要被映射到连续的物理地址中,当程序引用到不在物理地址中的页时,硬件执行操作将缺失的页装入物理内存.

📖2. 写时拷贝

此时我们便可以解释上述代码中发生的现象:

image-20221029160757322

image-20221029161106770

我们将这种行为称为写时拷贝等到修改数据时才分配内存空间,这是对程序性能的优化,可以延迟甚至是避免内存拷贝,目的是避免不必要的内存拷贝

📖3. 虚拟地址空间的优点

  1. 对内存提供保护

物理内存本身是不受限制访问的,任何地址都可以读写,而操作系统要求不同的页面具有不同的访问权限,这是利用CPU模式MMU的内存保护机制实现的。例如,Text Segment被只读保护起来,防止被错误的指令意外改写,内核地址空间也被保护起来,防止在用户模式下执行错误的指令意外改写内核数据。这样,执行错误指令或恶意代码的破坏能力受到了限制,顶多使当前进程因段错误终止,而不会影响整个系统的稳定性

  1. 让每个进程都拥有独立的地址空间

所谓独立的地址空间是指,不同进程中的同一个VAMMU映射到不同的PA,并且在某一个进程中访问任何地址都不可能访问到另外一个进程的数据,这样使得任何一个进程由于执行错误指令或恶意代码导致的非法内存访问都不会意外改写其它进程的数据,不会影响其它进程的运行,从而保证整个系统的稳定性。另一方面,每个进程都认为自己独占整个虚拟地址空间,这样链接器和加载器的实现会比较容易,不必考虑各进程的地址范围是否冲突

  1. 虚拟地址到物理地址的映射给分配和释放内存带来方便

物理地址不连续的几块内存可以映射成虚拟地址连续的一块内存。比如要用malloc分配一块很大的内存空间,虽然有足够多的空闲物理内存,却没有足够大的连续空闲内存,这时就可以分配多个不连续的物理页面而映射到连续的虚拟地址范围

  1. 一个系统如果同时运行着很多进程,为各进程分配的内存之和可能会大于实际可用的物理内存,虚拟内存管理使得这种情况下各进程仍然能够正常运行

因为各进程分配的只不过是虚拟内存的页面,这些页面的数据可以映射到物理页面,也可以临时保存到磁盘上而不占用物理页面,在磁盘上临时保存虚拟内存页面的可能是一个磁盘分区,也可能是一个磁盘文件,称为交换设备(Swap Device)。当物理内存不够用时,将一些不常用的物理页面中的数据临时保存到交换设备,然后这个物理页面就认为是空闲的了,可以重新分配给进程使用,这个过程称为换出(Pageout)。如果进程要用到被换出的页面,就从交换设备再加载回物理内存,这称为换入(Pagein)。换出和换入操作统称为换页(Paging)

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

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

相关文章

OpenTCS客户端开发之Web客户端(一)

越来越多人私信我关于OpenTCS的问题。可以感觉到很多人对OpenTCS的研究的人多了很多&#xff0c;很好。这些问题很多是关于算法方面的&#xff0c;也有一部分是关于UI方面的&#xff0c;毕竟OpenTCS本质上是一个算法项目&#xff0c;但是如果希望把它进行商业化&#xff0c;那免…

【微服务】服务拆分和远程调用

2.1 服务拆分原则 这里总结了微服务拆分时的几个原则&#xff1a; 不同微服务&#xff0c;不要重复开发相同业务微服务数据独立&#xff0c;不要访问其它微服务的数据库微服务可以将自己的业务暴露为接口&#xff0c;供其它微服务调用 2.2 服务拆分示例 以微服务cloud-demo为…

第三节:运算符【java】

目录 &#x1f392;运算符 &#x1f4c3;1. 什么是运算符 &#x1f4d7;2. 算术运算符 2.1 基本四则运算符&#xff1a;加减乘除模( - * / %) 2.2 增量运算符 - * % 2.3 自增/自减运算符 -- &#x1f4d9;3. 关系运算符 &#x1f4d5;4.逻辑运算符(重点) 4.1 逻辑与…

隔离出来的“陋室铭”

被隔离了 日常锻炼身体就是去公司旁边的酒店游泳&#xff0c;结果酒店里除了小阳人&#xff0c;我就喜提次密称号&#xff0c;7天隔离走起&#xff1b;又因为不想耽误家里孩子上学&#xff0c;老人外出&#xff0c;就选择了单独隔离&#xff0c;结果就拉到了单独的隔离点&…

精通Git(三)——Git分支机制

文章目录前言分支机制简述创建分支切换分支基本的分支与合并操作基本的分支操作基本的合并操作基本的合并冲突处理分支管理与分支有关的工作流长期分支主题分支远程分支推送跟踪分支拉取删除远程分支变基基本的变基操作变基操作的潜在危害只在需要的时候执行变基操作变基操作与…

C++——vector容器的基本使用和模拟实现

1、vector的介绍 vector是表示可变大小数组的序列容器。 就像数组一样&#xff0c;vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素 进行访问&#xff0c;和数组一样高效。但是又不像数组&#xff0c;它的大小是可以动态改变的&#xff0c;而且…

【动手学深度学习PyTorch版】18 使用块的网络 VGG

上一篇请移步【动手学深度学习PyTorch版】17 深度卷积神经网络 AlexNet_水w的博客-CSDN博客 目录 一、使用块的网络 VGG 1.1 AlexNet--->VGG ◼ VGG网络简介 1.2 VGG架构 1.3 总结 二、VGG网络的代码实现 2.1 VGG网络&#xff08;使用自定义&#xff09; 一、使用块的…

软件测试基本概念

目录本章要点什么是软件测试?软件测试的特定?软件测试和开发的区别?软件测试和软件开发中的调试有什么区别?软件测试在不同公司的定位?一个优秀的测试人员应该具备的素质(你为啥要选择测试开发)需求是衡量软件测试的依据从软件测试人员角度看需求为啥需求对软件测试人员如…

SpringBoot 面试题总结 (JavaGuide)

SpringBoot 面试题总结 &#xff08;JavaGuide&#xff09; 用 JavaGuide 复习 SpringBoot 时&#xff0c;找到一些面试题&#xff0c;没有答案&#xff0c;自己花了一天时间在网上找资料总结了一些&#xff0c;有些答案的来源比较杂忘了没有标注&#xff0c;望见谅。 1. 简单…

Visual Studio 2022开发Arduino详述

目录&#xff1a; 一、概述 二、软件的下载与安装 1、前言 2、Visual Studio 2022的下载与安装 3、Visual Micro扩展插件的导入 4、Visual Micro的使用 1&#xff09;安装修改插件 2&#xff09;搜索 : Visual.Micro.Processing.Sketch.dll 3&#xff09;打开Visual.…

【Linux学习】基础IO

目录前言一、C语言文件IO1. C语言文件接口以及打开方式2. 对当前路径的理解3. 默认打开的三个流二、 系统文件IO1. 系统接口openwritereadclose系统接口和库函数2. 文件描述符及其分配规则文件描述符文件描述符分配原则3. 重定向及dup2系统调用重定向标准输出和标准错误的区别d…

Linux XWindow的安装和配置

1.开始安装XWindow必须需要的组件 输入指令&#xff1a;yum groupinstall "X Window System" yum groupinstall "X Window System" 选择y继续安装。 当看到complete表示已经安装成功了。 输入startx测试一下 看到如上界面就证明你的XWindow安装成功了。 2…

Python数据分析(3):pandas

文章目录二. pandas入门2.1 数据结构2.1.1 Series对象2.1.2 DataFrame对象2.2 读取数据2.2.1 读取Excel&#xff1a;read_excel()1. 读取特定工作簿&#xff1a;sheet_name2. 指定列标签&#xff1a;header3. 指定行标签&#xff1a;index_col4. 读取指定列&#xff1a;usecols…

TypeScript接口——interface

目录 一、接口概述&#xff1a; 二、接口类型介绍&#xff1a; 1、属性接口&#xff1a; 2、 函数接口&#xff1a; 3、可索引接口&#xff1a; &#xff08;1&#xff09;可索引接口约束数组示例&#xff1a; &#xff08;2&#xff09; 可索引接口约束对象示例&#xf…

【Python】numpy矩阵运算大全

文章目录前言0 遇事不决&#xff0c;先查官网&#xff0c;查着查着就查熟了1 矩阵运算及其必要性2 矩阵的创建2.1 普通矩阵2.2 特殊矩阵3 矩阵的索引3.1 str, list, tupple的索引3.2 numpy索引4 矩阵的运算4.1 通用函数与广播机制4.3 矩阵乘法4.4 矩阵求逆4.5 矩阵转置4.6 向量…

SpringBoot整合mybatis-plus 实现增删改查和分页查询

SpringBoot整合mybatis-plus 实现增删改查和分页查询整体的运行图片&#xff1a;一、环境搭建&#xff1a;1、依赖2、application.yml文件3、数据库二、实体类&#xff1a;三、数据层开发——基础CRUD四、业务层开发——分页功能制作4.1分页配置类 configuration4.2service接口…

【Node.js】模块化学习

Node.js教学 专栏 从头开始学习 目录 模块化的基本概念 什么是模块化 现实中的模块化 编程领域中的模块化 模块化规范 Node.js中的模块化 Node.js中模块的分类 加载模块 Node.js中的模块作用域 什么是模块作用域 模块作用域好处 向外共享模块作用域中的成员 module对象 modu…

第二站:分支与循环(终幕)一些经典的题目

目录 一、计算n的阶乘 1.一般解法 2.优化不能表示出较大数的阶乘 二、 计算 1!2!3!……10! 1.循环嵌套解法 2.一次循环解法(优化计算时间) 三、在一个有序数组中查找具体的某个数字n 1.遍历查找 2.二分查找算法&#xff08;优化了查找时间&#xff09; 四、编写代码&am…

IDEA Out of memory 问题

文章目录1. 前提2. 问题记录与解决方案1. 前提 阅读本文之前&#xff0c;读者要首先把 Out of memory 这个问题的解决方案多搜几个帖子&#xff0c;先按照其他帖子的解决方案&#xff08;修改配置文件Xmx属性等&#xff09;尝试一遍&#xff0c;不能解决再参考本文。 本文所描…

前端小游戏——植物大战僵尸

给大家分享一个植物大战僵尸网页游戏源代码&#xff0c;感兴趣的小伙伴可收藏学习 &#x1f449;完整源码 文章目录⌛️效果展示⌛️游戏介绍⌛️游戏内容&#xff08;1&#xff09;冒险模式&#xff08;2&#xff09;小游戏⌛️图片资源⌛️代码展示&#xff08;1&#xff09;…