zoukankan      html  css  js  c++  java
  • 浅谈操作系统栈和堆(区别与联系)

    操作系统栈和堆

    地址空间布局:
    -c

    栈:

            执行期间编译器自动分配,编译器用它实现函数调用,调用函数时,栈增长,函数返回时,栈收缩。局部变量、函数参数、返回数据、返回地址等放在栈中

    栈的特点

    1. 内存分配取决于编译器,用户栈在程序运行期间可以动态的扩展和收缩。
    2. 和数据结构中的“栈”本质上是不一样的,但是操作方式类似于栈。
    3. 数据从栈中的进出满足“后进先出”的规律。
    4. 栈向低地址方向增长,esp(栈指针)指向栈顶元素。

    堆:

            动态储存器分配器维护着的一个进程的虚拟存储器区域。一般由程序员分配释放(堆在操作系统对进程初始化的时候分配),若程序员不释放,程序结束时可能由OS回收,每个进程,内核都维护着一个变量brk指向堆顶。

    堆的特点

    1. 内存分配取决于程序员,C/C++可以手动释放该片内存。
    2. 和数据结构的”堆“完全两回事,没有半点关系,在这里堆的结构更像链表。
    3. 所有的对象,包括数组的对象都存在堆上。
    4. 堆内存被所有的线程共享。
    5. 引用类型总是放在堆中。
    6. 堆向高地址方向增长,内核都维护的变量brk指向堆顶。

    注意:值类型和指针总是放在他们被声明的地方(复杂)
    当值类型的数据在方法体内被声明时,它们都应该放在栈上。
    如果一个只类型被声明在方法体外且存在于一个引用类型中,那么它将会被堆里的引用类型所取代。

    全局区/静态区:

            全局变量、静态变量、常量的存储区域,程序终止时系统释放。

    文字常量区:

            存放常量字符串,程序结束后由系统释放。

    程序代码区:

            存放函数体(类成员函数和全局函数)的二进制代码。

    实例

    int a = 0;        //全局初始化区
    char *p1;       //全局未初始化区
    void main()
    {
        int b;          //栈
        char s[] = "123";  //栈
        char *p2;       //栈
        char *p3 = "sdfghhj"; //其中,“sdfghhj”常量区,p3在栈区
        static int c = 0; //全局区
        p1 = (char*)malloc(10);   //10个字节区域在堆区
        strcpy(p1,"sdfghhj");    //"sdfghhj"在常量区,编译器可能会优化p1和p3指向同一块区域
    
    }
    
    

    栈和堆的区别:

    1. 栈内存存储的的是局部变量,堆内存存储的是实体。
    2. 栈内存的更新的速度会更快些(局部变量),堆内存的更新速度相对更慢。
    3. 栈内存的访问直接从地址读取数据到寄存器,然后放到目标地址,而堆内存的访问更麻烦,先将分配的地址放到寄存器,在读取地址的值,最后再放到目标文件中,开销更大。
    4. 栈内存是连续的空间,堆内存一般情况不是连续的,频繁地开辟空间,释放空间容易产生内存碎片(外碎片)。

    栈和堆的联系:

            堆中对象是直接由栈中的句柄(引用)管理者,所以堆负责产生真实对象,栈负责管理对象。

  • 相关阅读:
    为知笔记 Markdown 新手指南
    如何在服务器正确的看日志呢?
    如何查看网络之间是否互通
    自定义异常以及异常的处理
    记录下工作中用到的Linux命令
    fastJson中常用方法以及遇到的“坑”
    Java语法清单-快速回顾(开发)
    kafka的简单命令
    Elasticsearch集群状态查看命令
    ElasticSearch学习文档2018.11
  • 原文地址:https://www.cnblogs.com/wsq-888/p/cao-zuo-xi-tong-zhan-he-dui.html
Copyright © 2011-2022 走看看