当前位置: 首页 > news >正文

【Linux】进程地址空间(虚拟地址vs物理地址vs页表)

Linux 进程概念补充【Linux】 进程是什么(不熟悉的兄弟可以看看)。

1. C/C++内存分布图

对于有c/c++基础的同学相信对上面的图片并不陌生,实际上其描述的并不是正真的物理内存,而是虚拟内存,我们把它叫做进程地址空间 。

2. 虚拟内存与物理内存的转换

1.在task_struct(PCB)有mm_struct字段描述了虚拟内存。(所以一个进程管理一个mm_struct保证了进程间的数据独立

2.简单来说在虚拟内存与物理内存之中我们是用页表来建立映射关系的。

3. 虚拟内存的优点 

1.将物理内存从无序变为有序,使进程以统一的视角来看待内存。

2.将进程管理与内存管理进行解耦。

3.虚拟内存+页表保证了安全性。例如程序访问野指针程序崩溃而操作系统没有崩溃。

4. 父子进程相关问题

我们知道父子进程代码共享。其中数据各自开辟空间,私有一份(采用写时拷贝)

代码实验:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int g_val = 100;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);}}
}

有了上面的理论基础我们不难理解,虽然父子进程代码共享但是每个进程都有自己独立的进程地址空间,所以虽然父子进程的g_val地址相同,但是这只是虚拟地址所以其真正的物理地址并不相同故打印出来的值不同。 

下面再来解释一下写时拷贝:

 

我们把这种操作叫做写时拷贝。

写时拷贝的目的

  1. 节省内存:当一个进程创建子进程时,如果不使用写时拷贝,那么操作系统会为子进程复制父进程的所有内存页。这不仅增加了内存占用,还可能导致不必要的数据复制,特别是在子进程只是短暂存在或不会修改大部分数据的情况下。写时拷贝允许父子进程共享相同的物理内存页,直到任何一个进程尝试修改这些页。

  2. 快速创建进程:由于不需要立即复制所有的内存页,进程创建速度更快,尤其是在父进程有大量内存占用的情况下。

  3. 按需分配资源:只有当实际需要对某一页进行写入操作时,才会触发该页的复制,从而实现更有效的资源管理。

写时拷贝的优点

  1. 高效利用资源:通过避免不必要的内存页复制,操作系统可以更有效地利用可用的物理内存,这对于多任务处理环境尤为重要。

  2. 提升性能:对于那些只读取数据而不做修改的子进程,性能提升尤为明显,因为它们不需要等待内存页的复制完成就可以开始执行。

  3. 简化进程间通信:如果父子进程之间需要共享某些只读数据,写时拷贝机制允许它们直接共享这些数据而无需额外的通信机制。

  4. 降低上下文切换开销:由于减少了内存页的复制,也相应地减少了与内存管理相关的上下文切换次数,这有助于提高系统的整体性能。

  5. 支持非阻塞操作:子进程可以在不阻塞父进程的情况下启动,这对并行计算和并发编程非常重要

http://www.lryc.cn/news/495426.html

相关文章:

  • pytorch 融合 fuse 学习笔记
  • 在 Ubuntu 20.04 上使用 Lux 下载 Bilibili 视频的详细教程
  • 【eclipse】快捷键
  • 集成开发环境(IDE)的使用技巧插件配置
  • 【如何提升代码工程质量】code review篇
  • Qt 面试题学习13_2024-12-1
  • Hive 安装与架构详解
  • 前端入门指南:模块打包器是什么?模块打包器的工作原理与实践
  • 初识ProtoBuf以及环境搭建(Win和Ubuntu)
  • springboot366高校物品捐赠管理系统(论文+源码)_kaic
  • 【Python网络爬虫笔记】5-(Request 带参数的get请求) 爬取豆瓣电影排行信息
  • 递归算法讲解(c基础)
  • AJAX一、axios使用,url组成(协议,域名,资源路径)查询参数和化简,错误处理,请求/响应报文,状态码,接口文档,
  • QT6学习第六天 初识QML
  • 映射vim键位,基本功能键位表(未更完)
  • Python学习笔记(5)Python的创建型设计模式
  • qt QAnimationDriver详解
  • 零拷贝相关知识点(一)
  • STM32的CAN波特率计算
  • 简单好用的折线图绘制!
  • Hadoop批量计算实验
  • 基于rpcapd与wireshark的远程实时抓包的方法
  • ubuntu多版本安装gcc
  • 算法刷题Day1
  • 泛化调用 :在没有接口的情况下进行RPC调用
  • Java 泛型详细解析
  • 题解:CF332B Maximum Absurdity
  • Vue 集成和使用 SQLite 的完整指东
  • 【JVM什么时候触发YoungGC和FullGC】
  • ubuntu配置网络