Linux系统中进程内存分布

4 篇文章 0 订阅

Linux中进程内存的分布

1.内存分布

以32位系统为例,共有4G的寻址能力,进程在内存中的分布如下图所示。Linux默认将高地址的1G空间分配给内核,称为内核空间,剩下的3G空间分配给进程使用,称为用户空间。

用户空间从低地址空间到高地址空间包含如下5个部分:

  • 代码段(text segment):存放程序的可执行二进制代码
  • 数据段(data segment):存放程序中已经初始化且初值不为0的全局变量和静态局部变量,数据段属于静态内存分配
  • BSS段:存放未初始化的全局变量和静态局部变量;初值为0的全局变量和静态局部变量
  • 堆(heap):用于存放程序运行时动态分配的内存段,可动态扩张或者缩减
  • 栈(stack):由编译器自动分配释放,它存放如下信息:
    1. 函数内部声明的非静态局部变量
    2. 记录函数调用过程的相关维护信息(称为栈帧)
  • 内存映射区域:可以用于内存映射,或者装在动态链接库

2.栈

一个栈的实例如下图所示:

在这里插入图片描述
esp寄存器指向栈顶,通过控制esp寄存器可以实现数据的压缩和弹出。栈在程序的运行中非常重要,保存了一个函数调用所需维护的信息,通常被称为栈帧(Stack Frame),一个栈帧通常包含如下几个部分:

  • 函数的返回地址和参数
  • 临时变量:函数的非静态局部变量和编译器自动生成的其他临时变量
  • 保存的上下文:函数在调用前后需要保持不变的寄存器

一个函数的栈帧通常使用ebp和esp这两个寄存器来划定范围。esp寄存器始终指向栈的顶部,ebp指向栈帧的一个固定位置,ebp寄存器又被称为帧指针。一个常见的栈帧如下图所示:

在这里插入图片描述

3.堆

程序可以在堆上自由地申请空间使用,例如使用malloc申请内存空间。在实际实现过程中,程序会像操作系统申请一块适当大小的堆空间,然后由程序自己管理这块空间。这样可以避免每次申请内存都使用系统调用,带来的性能开销。

堆空间管理涉及到如下两个系统调用:

  • brk(): 设置进程数据段的结束地址,即它可以扩大和缩小数据段。如果将数据段的结束地址向高地址移动,扩大的那部分空间可以被程序使用。Glibc中还有一个函数叫sbrk(),它以一个增量作为参数,即增加(或减少)的空间大小,返回值是增加(减少)后数据段的结束地址,sbrk()是对brk()系统调用的包装。
  • mmap(): 它的作用是向操作系统申请一段虚拟地址空间,该虚拟空间可以映射到某个文件,如果不将该地址映射到某个文件时,这块虚拟空间称为匿名空间,匿名空间可以拿来作为堆空间。
  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值