既然堆已经可以管理变量的生命周期,那么栈的作用个是什么?
2017-08-09 15:15
411 查看
首先汇编里,变量的概念几乎没有了,有的只是各种内存地址,不管是实地址还是虚地址,你访问一个变量就是靠地址,所以如果你不记住一个变量的地址,你就没办法去操作它,这就产生了问题,如果你的程序要1000个变量,你就把他们的地址全记下来吗?这显然是不现实的,首先这会浪费很多空间,因为几乎任何操作都离不开操作变量,也就是地址,那么就相当于你要用两倍甚至更多的空间来表示你的程序,而一半浪费在地址上,其次这样写程序也是没有效率的,1000个变量,难道你能把他们的地址全背下来吗?或者说当你看到地址0x1234的值赋值给地址0x2345时,你如何记得起0x1234和0x2345是两个干什么用的变量?
所以以一种系统的方法管理内存就显得尤为重要,毕竟我们要用计算机来方便自己,而不是拿来自虐。经过很多人的摸索,人们发现变量主要是两种形式,一种内容短小(比如一个int整数),需要频繁访问,但是生命周期很短,通常只在一个方法内存活,而另一种内容可能很多(比如很长一个字符串),可能不需要太频繁的访问,但生命周期较长,通常很多个方法中可能都要用到,那么自然将这两类变量分开就显得比较理性,一类存储在栈区,通常是局部变量、操作符栈、函数参数传递和返回值,另一类存储在堆区,通常是较大的结构体(或者OOP中的对象)、需要反复访问的全局变量。
堆区就是各种慢,申请内存慢,访问慢,修改慢,释放慢,整理慢(或者说GC垃圾回收),但优点也不言而喻,访问随机灵活,空间超大,在不超可用内存的情况下你要多大就给多大。
栈区就像临时工,干完就跑,所以超快,但是缺点也很多,比如生命周期短,一般只能在一个方法内存活,又比如你需要事先知道需要多大的栈(事实上绝大多数语言栈区要分配的大小编译期就确定了,Java就是这样),而且通常最大栈区可用内存都很小,你不可能往栈区里堆很多数据。
总之,栈虽然能够解决变量声明周期和变量地址的管理,但是对于那些内容较大的变量来说,存储在栈中无疑增加了栈的体积,随着栈的体积的增加必然增加栈的搜索复杂度,从而失去了栈存在的意义(快速的获取变量地址,高效管理内存,控制变量的生命周期),因此引入堆的概念,在栈中只存储简单的地址,使栈基本上真正实现只存储变量地址(虽然值类型数据内容也存储在栈中,但是内容短小),通过控制变量地址是否在栈中控制变量的生命周期以及高效的管理地址。
所以以一种系统的方法管理内存就显得尤为重要,毕竟我们要用计算机来方便自己,而不是拿来自虐。经过很多人的摸索,人们发现变量主要是两种形式,一种内容短小(比如一个int整数),需要频繁访问,但是生命周期很短,通常只在一个方法内存活,而另一种内容可能很多(比如很长一个字符串),可能不需要太频繁的访问,但生命周期较长,通常很多个方法中可能都要用到,那么自然将这两类变量分开就显得比较理性,一类存储在栈区,通常是局部变量、操作符栈、函数参数传递和返回值,另一类存储在堆区,通常是较大的结构体(或者OOP中的对象)、需要反复访问的全局变量。
堆区就是各种慢,申请内存慢,访问慢,修改慢,释放慢,整理慢(或者说GC垃圾回收),但优点也不言而喻,访问随机灵活,空间超大,在不超可用内存的情况下你要多大就给多大。
栈区就像临时工,干完就跑,所以超快,但是缺点也很多,比如生命周期短,一般只能在一个方法内存活,又比如你需要事先知道需要多大的栈(事实上绝大多数语言栈区要分配的大小编译期就确定了,Java就是这样),而且通常最大栈区可用内存都很小,你不可能往栈区里堆很多数据。
总之,栈虽然能够解决变量声明周期和变量地址的管理,但是对于那些内容较大的变量来说,存储在栈中无疑增加了栈的体积,随着栈的体积的增加必然增加栈的搜索复杂度,从而失去了栈存在的意义(快速的获取变量地址,高效管理内存,控制变量的生命周期),因此引入堆的概念,在栈中只存储简单的地址,使栈基本上真正实现只存储变量地址(虽然值类型数据内容也存储在栈中,但是内容短小),通过控制变量地址是否在栈中控制变量的生命周期以及高效的管理地址。
相关文章推荐
- 汇编语言中可以定义变量吗?怎么定义?有局部变量和全局变量之分吗?作用域是什么?
- [Javascript]闭包是可以访问上一层函数作用域里变量的函数,即便上一层函数已经关闭
- 函数里面有函数叫函数的闭包:子函数可以调用父函数变量,如果子函数找不到变量,那么整条作用域链的变量都会被保存
- volatile定义变量的作用是什么?
- const和volatile是否可以同时修饰一个变量?有什么特殊含义?
- 环境变量path和classpath的作用是什么?
- 程序员是一个什么能力都可以发挥作用的平台
- 程序员是一个什么能力都可以发挥作用的平台
- ArrayList既然继承自AbstractList抽象类,而AbstractList已经实现了List接口,那么ArrayList类为何还要再实现List接口呢?
- NSMutableArray 如果只进行了声明,而没有进行初始化,那么程序不会报错,但是,声明的那个变量不起任何作用
- 请问有没有人知道可不可以根据已经编译好的exe(这里具体指窗体),通过什么工具可以看到它里面的某一个控件的事件里面的代码(比如timer的tick)。
- 设置jdk环境变量时lib中的rt.jar ,dt.jar ,tool.jar是什么,作用是什么
- C#学习回顾笔记三:变量是什么,变量有什么作用
- 针对计划和监控,项目管理可以做什么?
- 20110415-既然输出操作符返回的是其左操作数,那么我们就可以将输出请求链接在一起。
- 既然Eclipse、tomcat只需要jre,那么jdk有什么用呢? 答案:没用
- 当一个变量已经定义为一个数据类型时,可以改变他的数据类型吗
- 理论计算机图形渲染技术是否已经到了没有什么可以研究的地步了?
- 环境变量path和classpath的作用是什么?
- 变量类型,作用域,存储空间,生命周期