2.4内存管理

2.4.1进程内存布局

        进程的内存以及内存地址,指的都是“虚拟内存”和“虚拟内存地址”,之所以是虚拟的,因为Linux操作系统为了更好、更高效的使用内存,对实际物理内存进行了映射。

1.栈内存

        按照“后进后出”的逻辑进行操作,全称是“运行时栈”(Run-time Stack):顾名思义栈会随着进程的运行而不断发生变化;一旦有新的函数被调用,就会立即在栈顶分配一帧内存,专门用于存放该函数内定义的局部变量;当一个调用的函数执行完毕返回时,他所占用的那帧内存将被立即释放。

        但栈的大小是有一个最大限度的,一般是8M;如果进程嵌套调用了很多函数,会导致栈不断增长,超过这个最大值会产生所谓的“栈溢出”导致程序崩溃。

        参照上图:着重注意以下几点:

        (1)一个C程序的栈由若干段函数的栈帧组成,每一段栈帧都用来存放对应函数的局部变量;占用内存较多或者不确定的数据应使用堆内存(栈帧的长度是有最大限度的:8M)。

        (2)每个函数的栈帧都是独立存在的,里面的局部变量也是相对独立的。

        (3)函数调用时,所有的形参被实参一一初始化,要保证函数调用时传递的参数一定要和函数的定义的接口一致。

        (4)栈内存最重要的特性:临时性。一旦对应的函数退出,相应的栈帧将立即被释放(被系统回收)。

 2.堆内存

        堆内存是一块自由内存,在这个区域定义和释放变量完全由用户决定,即所谓的自由区;堆和栈的最大区别是:堆是不设大小限制的,最大值取决于系统的物理内存

3.数据段

        分为3部分,地址从高到低分别是:.bss段,.data段, .rodata段

        (1).bss: 专门存放未初始化的静态数据,他们都将被初始化为0

        (2).data: 抓门存放已经初始化的静态数据

        (3).rodata: 用来存放只读数据,即常量,比如进程中所有的字符串、字符常量等

 4.代码段

        分为两部分

        (1).text:存放用户程序代码,也就是包括main函数在内的所有用户自定义函数

        (2).init:存储系统给每一个可执行程序自动添加的“初始化”代码

        对上图做几点说明:

        (1)栈中的环境变量和命令行参数在程序一开始运行之时就被固定在了栈底,且进程在整个运行期间不再发生变化;假如进程运行时对环境变量的个数或者值做了修改,则为了容纳修改后的内容,新的环境变量将被赋值到堆里       

        (2)“栈”还有一个名称为“堆栈” ,堆栈和堆没有一点关系

        (3)栈和堆都是动态变化的,分别向下和向上增长,大小随着进程的运行不断变大变小

        (4)静态数据指的是所有的全局变量以及static型局部变量

        (5)数据段的大小在进程一开始运行就是固定的

          (6)   尽量避免使用静态数据,至少两个缺点:1.生命周期与整个进程相当,无条件的一直占用内存 2.静态数据的全局变量是典型的共享资源,在多线程程序中,无法简单粗暴的使用

2.4.2 堆(Heap)

        堆内存被称为内存中的自由区,在此区域定义的内存的生命周期是我们可以控制的,

        堆内存的生命周期:从malloc()、calloc()、realloc()开始,到free()结束,其分配和释放由我们开发者自定义,让程序在运行的过程中,以最大的效益使用内存

        范例:

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值