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

    关于内存的使用,栈(stack)和堆(heap)是非常重要的两个概念,网上讲解的资料也比较多,大家也应该知道栈和堆分别的用途是什么,接下来说一下我对栈与堆的本质区别的理解。

    每个程序在运行时系统都会分配一块叫做栈的连续的内存区域,大小一般为1M或2M,是编译程序时指定的常数。堆则是系统中所有空闲的内存区域,因此是不连续的,而且有可能是虚拟内存。函数的调用和返回是通过栈来实现的,不细说了。程序中用到的变量(对象)所占据的内存空间既可以从栈上分配,也可以从堆中分配,区别如下:

    1. 内存指针的性质不同

    栈上面只能分配长度较小、大小固定的数据,变量的内存地址相对于栈指针的偏移量在编译时就可以确定,因而可以生成直接的内存访问的指令。

    堆上面分配的空间大小在运行时指定,并且返回的内存地址只能在运行时得知,因此栈上需要有一个相应的变量来保存堆上分配的内存地址,地址的长度为32位或64位。于是访问堆上的内存单元只能通过间接访问的指令来操作。

    2. 内存空间的回收方式不同

    栈上面分配的内存在压栈和出栈的过程中自动分配自动回收,速度很快。

    堆上面分配的内存则需要显式地释放掉或者做垃圾回收的处理,有可能会漏掉释放,造成所谓的内存泄漏。

    理解栈和堆的概念对于编写正确的高效的程序非常重要,但是程序语言的语法对栈和堆的体现很隐晦。C++创建一个类的实例时,既可以指定在栈上分配,也可以指定在堆上分配。C#中值类型的变量在栈上分配,引用类型的变量在堆上分配,值类型的变量也可以通过装箱的方式在堆上分配,在unsafe代码中可以在栈上分配大小固定的字节数组,总的来说没有C++灵活。

    最后做一个练习,思考一下下面的程序在运行中内存是怎样分配的:

    public struct A
    {
        
    int field;
        List
    <int> list = new List<int>();
    }

    public class B
    {
        
    int field;
        List
    <A> list = new List<A>();
    }

    public class P
    {
      
    static void main(string[] args)
      {
          A a 
    = new A();
          B b 
    = new B();
          Console.Write(
    "{0} and {1}", a, b);
      }
    }
  • 相关阅读:
    区分/不区分大小写的比较,查找字符串在另一字符串中的位置,字符串开头是否包括另一字符串 hasPrefix
    获取文件名以及后缀
    监听Documents文件夹内文件发生改变
    根据路径获取文件大小
    获取视频第一帧的方法
    判断图片格式
    iTunes文件共享
    iOS 10 隐私权限设置
    uCos 学习:0-有关概念
    ALSA 有关文档
  • 原文地址:https://www.cnblogs.com/rufi/p/StackAndHeap.html
Copyright © 2011-2022 走看看