Linux中程序地址空间

很早接触到了虚拟地址和虚拟地址空间,今天总结一下

首先怎么看虚拟地址空间呢

int global = 0;
int main()
{
	 pid_t pid = fork();
	 if(pid < 0){
		 perror("fork");
		 return 0;
 }
 else if(id == 0){ //child
	 printf("child[%d]: %d : %p\n", getpid(), g_val, &g_val);
 }else{ //parent
	 printf("parent[%d]: %d : %p\n", getpid(), g_val, &g_val);
 }
 sleep(1);
 return 0;
}

打印出结果结果地址是一样的
可以理解为子进程是以父进程为模板创造的,所以地址一样
那么对上面的代码进行改造

int global = 0;
int main()
{
	 pid_t pid = fork();
	 if(pid < 0){
		 perror("fork");
		 return 0;
 }
 else if(id == 0){ //child
 global = 1;
	 printf("child[%d]: %d : %p\n", getpid(), g_val, &g_val);
 }else{ //parent
	 printf("parent[%d]: %d : %p\n", getpid(), g_val, &g_val);
 }
 sleep(1);
 return 0;
}

打印会发现,地址依然一样,但是值不一样了,我们都知道,变量对应的是一块内存空间,里面存着变量的值,怎么可能内存空间一样但是储存的变量的值不同呢

因为这个地址不是物理地址,而时虚拟地址
代码共享(只读) 数据独有
为啥要虚拟空间
简单理解一下
为了更好的利用内存空间
那么在操作系统中是这么描述和分配一个虚拟地址空间的呢
没错是一个结构体描述的

struct mm_struct
			描述了一个完整的虚拟地址空间
			{
				ulong mem_size;//大小
				ulong code_start;//代码段开始位置
				ulong code_end;//代码段结束位置
			}

程序运行时需要连续的地址空间,虚拟地址连续,但是映射到物理地址上不是连续的,虚拟地址和物理地址之间有页表
虚拟地址空间可称为内存描述符
那么在创建子进程时,发生了什么
啊啊啊回忆学过的东西真头疼
那么发生了什么呢
首先,子进程是通过复制父进程创建的,包括父进程的页表,这也就是说明,现在子进程和父进程是指向同一块物理内存空间的,当内存的数据,变量发生改变时,操作系统会为子进程重新分配内存并开辟页表
这就是写实拷贝技术
进程也具有独立性
所以虚拟空间有什么用
1.提高内存利用率
2.可以内存访问控制
3.保持进程独立性

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值