您的位置:首页 > 运维架构 > Linux

Linux进程环境之进程虚拟空间及存储

2017-05-22 12:11 309 查看

程序的存储空间布局

程序由以下几部分组成(32位一共是3G):

1.正文段

由CPU执行的机器指令部分。通常,正文段可以共享,所以即使频繁的执行程序(shell、文本编辑器等),存储器中也只需有一个副本。

正文段一般是只读的,防止程序由意外而修改其指令。

2.初始化数据段

一般称为数据段,包含了程序中需要明确地赋初始值的变量:

int maxcount=99;


3.未初始化数据段

通常称为bss段,在程序执行之前,内核将此段中的数据初始化为0或空指针,例如:

long sum[1000];


4.栈

自动变量以及每次函数调用时所需保存的信息都存放在此段中。

5.堆

通常在堆中进行动态存储分配。



图1

另外对于一个进程的虚拟地址空间来说,32位CPU,0x0000 0000 到 0xffff ffff 一共有4G的虚拟地址,其中低的3G为进程空间所用,高地址的1G空间由操作系统使用

如图2



图2

存储空间分配

C有3个函数在堆中分配空间,1个函数用来释放空间:

#include <stdlib.h>
void *malloc(size_t size);//分配指定字节数的存储区。初始值不定
void free(void *ptr);//释放空间,但不一定归还堆,而是送回可用存储区池以便后续使用
void *calloc(size_t nmemb, size_t size);//分配空间且初始化为0
void *realloc(void *ptr, size_t size);//增加或者减少分配区长度。增加长度时,可能需要将以前分配区的内容移动到另一个更大的区域


如上图1,堆是向高地址扩充的,调用
realloc
时,如果有足够大的空间,可以直接在原位置想高地址方向扩充,否则需要移动换一个有足够大小的地址

当我们使用*alloc函数时,底层通常使用
sbrk(2)
来扩充或缩小进程的堆。

比如我们使用malloc申请10bytes字节,底层系统调用使用sbrk像OS申请4K大小的堆空间,这样下次再调用malloc时,就直接从这4K大小的空间中分配了。

参考

http://www.cnblogs.com/clover-toeic/p/3754433.html

http://stackoverflow.com/questions/19676688/how-malloc-and-sbrk-works-in-unix
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: