进程的私有地址空间构成?

在这里插入图片描述
一个程序本质上都是由.bss段、.data段、.text段(此处忽略.init和.rodata)三个组成的。可以看到一个可执行程序在存储(没有调入内存)时分为代码段数据区未初始化数据区三部分。

.bss段(未初始化数据区):通常用来存放程序中未初始化的全局变量静态变量的一块内存区域。.bss段属于静态分配,程序结束后静态变量资源由系统自动释放。

数据段:存放程序中已初始化的全局变量的一块内存区域。数据段也属于静态内存分配。

代码段:存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域属于只读。在代码段中,也有可能包含一些只读的常数变量(指.rodata)。

.text段和.data段在编译时已经分配了空间,而.bss段并不占用可执行文件的大小,它是由链接器来获取内存的。

.bss段的内容并不存放在磁盘上的程序文件中。其原因是内核在程序开始运行前将它们设置为0。需要存放在程序文件中的只有正文段和初始化数据段。

.data段则为数据分配空间,数据保存到目标文件中。数据段包含经过初始化的全局变量以及它们的值。.bss段的大小从可执行文件中得到,然后链接器得到这个大小的内存块,紧跟在数据段的后面(地址高于数据段),当这部分内存进入程序的地址空间后全部清零。包含.data段和.bss段的整个区段此时通常被称为“数据区”。

可执行程序在运行时又多出两个区域:栈区和堆区。

栈区:由编译器自动释放,存放函数的参数值、局部变量等。每当一个函数被调用时,该函数的返回类型和一些调用的信息就会被压栈,然后这个被调用的函数再为他的自动变量和临时变量在栈上分配空间。每调用一个函数一个新的栈帧就会被使用。栈区是从高地址位向低地址位增长的,是一块连续的内存区域,最大容量是由系统预先定义好的(Linux下通过ulimit -s命令可以查询),申请的栈空间超过这个界限时会提示溢出。用户能从栈中获取的空间较小。

堆区:用于动态分配内存,位于.bss和栈中间的地址区域。由程序员申请分配和释放。堆是从低地址位向高地址位增长,采用链式存储结构。频繁的malloc/free会造成内存空间的不连续,产生外部碎片。当申请堆空间时库函数是按照一定的算法搜索可用的足够大的空间。因此堆的效率比栈要低的多。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值