【Linux】进程地址空间(内存管理)

之前笔者写过C/C++的程序内存区域划分
https://blog.csdn.net/qq_43909184/article/details/96652054
在这里插入图片描述
关键点来了,这并不是计算机内存的实际使用情况,我们看到的程序地址空间实际是一个虚拟地址空间,实际上是操作系统通过mm_ struct这 个结构体为进程描述的一个空间,因此有时候也称作内存描述符。

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int g_val = 0;
int main() {
	pid_t id = fork();
	if(id < 0){
		perror("fork");
		return -1;
	} else if(id == 0){ //child,子进程肯定先跑完,也就是子进程先修改,完成之后,父进程再读取
		g_val=100;
		printf("child[%d]: %d : %p\n", getpid(), g_val, &g_val);
	}else{ //parent
		sleep(3);
		printf("parent[%d]: %d : %p\n", getpid(), g_val, &g_val);
	}
	sleep(1);
	return 0;
}
//输出结果
child[3046]: 100 : 0x80497e8
parent[3045]: 0 : 0x80497e8
  • 变量内容不一样,所以父子进程输出的变量绝对不是同一个变量
  • 但地址值是一样的,说明,该地址绝对不是物理地址!
  • 在Linux地址下,这种地址叫做 虚拟地址
  • 我们在用C/C++语言所看到的地址,全部都是虚拟地址!物理地址,用户一概看不到,由OS统一管理

如下图解释上述代码运行结果的原因:
在这里插入图片描述

OS是如何管理内存的

分页式:把进程虚拟地址空间分成一页一页,物理内存分成一块一块,页和块的大小相同。通过地址中的页号去页表找到页表项,通过页表项中的物理页号加上页内偏移获取到物理地址。
可以通过下面例题理解
在这里插入图片描述
分段式:通过地址中的段号去段表找到段表项,通过段表项中的物理段号加上地址中的段内偏移获取到物理地址。
在这里插入图片描述
段页式:通过段号在段表中找到段表项中的段内页表地址找到段内页表,通过地址中的段内页号在段内页表中找到页表项,通过页表项中的物理页号与页内偏移组成物理地址。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值