栈和堆存储学习总结

来源:互联网 发布:蜂鸟网络 深圳 编辑:程序博客网 时间:2024/06/05 08:52

          今天好好研读了下《编译原理》(青龙书)的运行时刻环境章节,终于对困惑了很久的栈和堆存储有了比较深入的了解。以前没有读书写博客总结的习惯,今天开始决定向技术大牛们学习,要把每一次的学习和经验总结写下来,加深理解也方便以后温习。下面内容主要源于书中的描述。


                        代码区                        静态区                         堆区
                      空闲空间
                          栈区 运行时刻内存被划分成代码区和数据区的典型方式


        程序编译后生成的目标代码的大小在编译时刻就已经固定下来了,因此编译器可以将执行目标代码放在一个静态确定的区域:代码区。这个区通常位于存储的低端。类似地,程序的某些数据对象的大小可以在编译时刻知道,它们可以被放置在另一个称为静态区的区域中,该区域被静态确定。放在这个区域的数据对象包括全局常量和编译器产生的数据,比如用于支持垃圾回收的信息等。

       为了将运行时刻的空间利用率最大化,另外两个区域——栈和堆被放在剩余地址空间的相对两端。这些区域是动态的,它们的大小会随着程序运行而改变。这两个区域需要向对方增长。栈区用来存放称为活动记录的数据结构,这些活动记录在函数调用过程中产生。在实践中,栈向较低地址方向增长,而堆向较高地址方向增长。

动态存储分配:

  1. 栈式存储。一个过程的局部名字(局部变量)在栈中分配空间。过程调用和返回通常由称为控制栈的运行时刻栈管理。
  1. 堆存储。有些数据的生命周期要比创造它的某次过程调用更长,这些数据通常被分配在一个可复用的“堆”中。堆是虚拟内存的一个区域,它允许对象或其他数据元素在被创建时获得存储空间,并在数据变得无效时释放该存储空间。虽然局部变量通常在它们所属的过程结束之后就变得不可访问,但很多语言支持创建某种对象或其他数据,他们的存在与否和创建它们的过程的活动无关。例如,C++Java语言都为程序员提供了new语句,该语句创建的对象(或指向对象的指针)可以在过程之间进行传递,因此这些对象在创建它们的过程结束之后仍然可以长期存在。这样的对象被放在堆区。编译器有个存储管理器专门管理堆内存的分配和回收。