zoukankan      html  css  js  c++  java
  • 堆和栈的区别

      堆和栈在程序的布局中是二个不同的组成部分。事实上,堆和栈都是内存的一个组成部分,通常把堆和栈联合起来称为堆栈。

    实际上堆是堆,栈是栈,堆和栈是完全不同的二个概念。下面从多个方面来区分堆和栈。

    1 内存分配:

    堆:由程序员负责申请,并提供需要申请的内存大小。堆使用完成后,由程序员负责显示释放。

      c语言: 堆的分配是用malloc()函数或者realloc()来完成的,堆的释放是用free()函数

      c++:堆内存用new运算符来分配,使用delete操作符负责释放。

    PS: 如果程序员忘记释放堆内存,会造成内存泄露。泄露的内存直到程序退出时才被操作系统回收。

    栈:由系统自动分配与释放。 栈一般用于存放函数的参数值,局部变量的值等。

      例如,声明在函数中一个局部变量 int b; 系统自动在栈中为b开辟空间。

      

    在内存资源分配的具体实现上,堆和栈也是有区别的:

    堆:堆的分配是通过操作系统的一个记录空闲内存地址的链表来实现的。当系统收到程序的内存申请时,会遍历该链表,寻找第一个

      空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序。另外,对于大多数系统,

      会在这块内存空间中的首地址处记录本次分配的大小,这样代码中的delete语句才能正确的释放本内存空间。另外由于找到的堆结点的

      大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。

    栈:每个进程都拥有自己的一个固定连续的栈空间。在系统分配的时候,只要栈的剩余空间大于所申请空间,系统将为程序提供内存,

      如果栈的剩余空间小于所申请空间,会报栈溢出异常。

    2 大小限制:

    堆:是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,

      而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。

    栈:在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,

      在Windows下,栈的大小是固定的(是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示栈溢出。因此,能从栈获得的空间较小。 

    Windows: 

    应用栈:默认1M,编译指令/stack可改设其他值 

    内核栈:系统根据CPU架构而定,x86系统上为12KB,x64系统上为24KB,安腾系统上为32KB 

    Linux: 

    应用栈:10M

    内核栈:4K或8K 

    在thread_info.h: 

    #ifdef CONFIG_4KSTACKS  

    #define THREAD_SIZE          (4096)  
    #else #define THREAD_SIZE          (8192) 

    3 效率比较

    堆:是由new分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便。值得注意的是,在Windows下,最好的方式是用 VirtualAlloc()分配内存,

    它既不是在堆也不是在栈,而是直接在进程的地址空间中保留一块内存,该方式虽然用起来最不方便,但是速度却更快,也最灵活。 

    栈:由系统自动分配,速度较快。但程序员是无法控制的。 

    4)存放内容: 

    堆:一般是在堆的头部用一个字节存放堆的大小,剩余部分存储的内容由由程序员根据程序计算的需要决定。 

    栈:栈是用来记录程序执行时函数调用过程中的活动记录(栈帧)。在函数调用时首先如栈的参数,在大多数的C编译器中,参数是由右往左入栈,然后是返回地址,

    紧接着是老ebp寄存器中的值,然后是分配函数中的局部变量。需要特别指出的是,静态变量存储在静态存储区,所以不入栈。当本次函数调用结束后,按照栈后进先出的顺序退栈,

    即局部变量先出栈,然后是老ebp和返回地址,然后是各个参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。

  • 相关阅读:
    237. Delete Node in a Linked List
    430. Flatten a Multilevel Doubly Linked List
    707. Design Linked List
    83. Remove Duplicates from Sorted List
    160. Intersection of Two Linked Lists
    426. Convert Binary Search Tree to Sorted Doubly Linked List
    142. Linked List Cycle II
    类之间的关系
    初始化块
    明确类和对象
  • 原文地址:https://www.cnblogs.com/fengxing999/p/11152635.html
Copyright © 2011-2022 走看看