• 堆栈的简单认识


        写堆栈,一是因为在工作中有时会碰到,脑子里有这个概念但是又没有一个完整的框架;二是我刚开始工作时,导师问我malloc,我竟完全不知这个函数,更不知道malloc是从堆中分配内存,所以现在补上。

             文中很多语句都是引用他人,无意抄袭,在此说明一下,若有冒犯,请告知。

             这篇文章先从程序内存布局讲起,说明堆栈在Linux进程内存空间中的位置,然后再分别说明堆栈的基本概念、作用。

    Linux进程内存布局

             现代的应用程序都是运行在内存空间中的,在32位的系统里,这个内存空间拥有4GB的寻址能力。实际上,每个应用程序(或者说进程)都有自己独立的内存空间,即通过虚拟内存来实现(具体虚拟内存知识暂不介绍)。

             大多数操作系统都会将4GB的内存空间中的一部分分配给内核使用,应用程序无法访问这一段内存,这一部分内存空间称之为内核空间。Linux默认将高地址的1GB内存空间分配给内核。剩下的3GB内存空间称之为用户空间。在用户空间里,也有许多默认的内存区域,例如堆栈,可执行文件映像,保留区。下图是一个Linux典型的内存布局:

                                                               

    一、什么是栈

             栈是现代计算机程序里最重要的概念之一,几乎每一个程序都使用了栈,没有栈就没有函数,没有局部变量。

        在经典的计算机科学中,栈被定义为特殊的容器,用户可以将数据压入栈中(入栈,push),也可以将已经压入栈中的数据弹出(出栈,pop),且栈遵守一条规则,即先入后出。

             经典的操作系统中,栈总是向下生长。在i386下,栈顶由称为esp的寄存器进行定位,压栈的操作会使栈顶的地址减小,弹出的操作使栈顶的地址增大。

    二、栈的作用是什么

             栈在程序运行中具有举足轻重的地位,最重要的,栈保存了一个函数调用所需要的维护信息,通常被称为堆栈帧(stack frame)或活动记录。堆栈帧一般包括以下几方面的内容:

        --函数的返回地址和参数

             --临时变量:包括函数的非静态局部变量以及编译器自动生成的其他临时变量

             --保存的上下文:包括在函数调用前后需要保持不变的寄存器

    一、堆的定义和作用

             光有栈对于面向过程的程序设计还远远不够,因为栈上的数据在函数返回的时候就会被释放掉,所以无法将数据传递至函数外部。而全局变量无法动态产生,只能在编译的时候定义,很多情况下缺乏表现力。在这种情况下,堆(heap)是唯一的选择。

             堆是一块巨大的内存空间,常常占据整个虚拟空间的绝大部分。在这片空间里,程序可以请求一块连续内存,并自由的使用,这块内存在程序主动放弃之前会一直保持有效。

             malloc是libc里面实现的一个函数,中文叫动态内存分配,用于从堆中获取内存。但是malloc是如何实现的呢?有一种实现方法是,将进程的内存管理交给操作系统去处理,既然内核管理着进程的地址空间,那么如果它提供一个系统调用,可以让程序使用这个系统调用来申请内存,这是一种理论上可行的方法,但是实际这样去做性能会非常差,因为每次程序申请或者释放堆空间都需要进行系统调用,而系统调用的性能开销非常大,当程序对堆的操作越频繁时,这样做的后果是会严重影响程序的性能。比较好的做法是程序向操作系统申请一块适当大小的空间,然后由程序自己管理,而具体来讲,管理着堆空间分配的往往是程序的运行库。

             运行库相当于是向操作系统“批发”了一块较大的堆空间,然后“零售”给程序用。当全部“售完”或者有大量的内存需求时,再根据实际需求向操作系统“进货”。运行库在向程序零售堆空间时,必须管理他批发来的堆空间,不能把同一块地址出售两次,于是运行库需要一个算法来管理堆空间,即堆的分配算法。

  • 相关阅读:
    Linux/Unix 新手和专家教程
    恢复Ext3下被删除的文件
    如何调试bash脚本
    8个实用而有趣Bash命令提示行
    使用grep恢复被删文件内容
    一些非常有意思的杂项资源
    chmod -x chmod的N种解法
    纯文本配置还是注册表
    面向对象的Shell脚本
    你可能不知道的Shell
  • 原文地址:https://www.cnblogs.com/Victor-Tian/p/7141886.html
Copyright © 2020-2023  润新知