进程空间结构 linux,进程地址空间

进程的地址空间

背景

Linux32位操作系统

内核版本:Linux version 2.6.32-754.3.5.el6.i686

Linux可执行程序文件空间布局

e64989c7606fb2a89c1805d7b2c8d63e.png

查看文件结构命令 size + 可执行文件名

size - list section sizes and total size.

The GNU size utility lists the section sizes---and the total size---for each of the

object or archive files objfile in its argument list. By default, one line of output

is generated for each object file or each module in an archive.

objfile... are the object files to be examined. If none are specified, the file

"a.out" will be used.

[liu@localhost 02]$ ls

env env.c getenv getenv.c orphan orphan.c

[liu@localhost 02]$ size env

text data bss dec hex filename

1195 252 12 1459 5b3 env

[liu@localhost 02]$

Linux进程空间结构

597253b32bb016d8fa43be92e18452eb.png

关于Linux进程空间结构

在进程第一篇博客提到:fork()会创建一个子进程,会复制父进程的所有资源,但是会拥有和父进程相独立的数据资源与代码区关于fork创建独立空间,以及程序证明的例子

既然创建了独立空间,那么来探究一下对于同一变量在父进程与子进程的地址显示为多少?

#include

#include

int _val = 100;

int main(void)

{

pid_t pid = fork();

if(pid < 0)

perror("fork : "),

exit(0);

else if(pid == 0)

{

printf("this is child _val : %d and it's addr : %p\n", _val, &_val);

}

else

{

printf("this is parent _val : %d and it's addr : %p\n", _val, &_val);

}

return 0;

}

输出结果 :

[liu@localhost jcaddr]$ ./addr

this is parent _val : 100 and it's addr : 0x80497b4

this is child _val : 100 and it's addr : 0x80497b4

改变一下:

[liu@localhost jcaddr]$ cat addr.c

#include

#include

int _val = 100;

int main(void)

{

pid_t pid = fork();

if(pid < 0)

perror("fork : "),

exit(0);

else if(pid == 0)

{

_val = 200;

printf("this is child _val : %d and it's addr : %p\n", _val, &_val);

}

else

{

_val = 50;

printf("this is parent _val : %d and it's addr : %p\n", _val, &_val);

}

return 0;

}

输出结果

[liu@localhost jcaddr]$ ./addr

this is parent _val : 50 and it's addr : 0x80497c4

this is child _val : 200 and it's addr : 0x80497c4

发现进程之间的变量确实是空间独立的,但是这两个进程的变量却是一样的。这样就引出了虚拟内存的概念。

早期的内存分派方式

4a38f7ccec41b80003b6b3d9f279ea0d.png

缺点:降低了效率,处理速度慢,难维护,产生了很多不必要的内存浪费。

分段

1.在编码的过程中,只要指名了所属段,代码和数据段中出现的所有地址都从0x00000000开始,映射关系完全由操作系统维护。

2.cpu将内存分割位不同的段,于是指令和数据的有效地址斌不是真正的物理地址二十相对于段首地址的偏移地址。

009be4a812e6fa4778fc3b53a6e901db.png

缺点:

分段之后,每个进程可能会剩余空间,虽然加快了处理速度,但是浪费了内存。

分段+虚拟地址空间

PCB中的一部分信息就是保存程序的地址空间(mm_struct),同过页表的映射到具体的物理空间,期间程序在物理内存被分段加载内存。

5d096733a2dff8b147231cab0b3f3faa.png

关于虚拟内存大小:

·在mm_struct上,都显示为物理内存的大小,这一点可以想到网盘的1T容可能人们单独用不了1T,所以一百个人可能硬盘10T就ok

关于Linux下的写时拷贝思想

·在fork创建子进程时,子进程复制整个父进程的PCB,包括页表在内,在对子进程中的数据进行操作的时候,页表才开辟新的物理内存,这一点可以类比C++中的写时拷贝

关于页表

·页表既可以将虚拟内存映射到物理内存,也维护着许多,包含有访问权限等等许多内容

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值