(delphi11最新学习资料) Object Pascal 学习笔记---第13章第1节 (全局数据、栈和堆)

13.1 全局数据、栈和堆**

​ 任何平台上的任何 Object Pascal 应用程序所使用的内存可以分为两个部分:代码和数据。就代码部分而言,程序可执行文件的指令部分、资源(如位图和窗体描述)以及程序使用的库都加载到其内存空间中。这些内存块是只读的,并且在某些平台(如 Windows 上)它们可以在多个进程之间共享。

​ 更有趣的是数据部分。Object Pascal 程序的数据(与大多数其他语言编写的程序一样)存储在三个明显不同的区域中:全局内存、栈和堆。

13.1.1 全局内存

​ 当 Object Pascal 编译器生成可执行文件时,它会程序在整个生命周期中存储存变量所需的空间。在一个Unit的interface或implementation中声明的全局变量属于此类别。请注意,如果全局变量是类类型(也包括字符串或动态数组),则只存储全局内存中的 4 字节或 8 字节对象引用。

​ 您可以在编译程序后使用 Project | Information 菜单项来确定全局内存的大小。您要查看的具体字段是数据大小。图 13.1 显示了近 50K 全局数据(48,956 字节)的使用情况,其中包括程序及其使用的库的全局数据。

图 13.1:已编译程序的信息

​ 全局内存有时被称为静态内存,因为一旦程序加载,变量将保留在原来的位置,因此在程序的生命周期内永远不会释放这些内存。

13.1.2

​ 栈是一个动态内存区域,按照后进先出(LIFO)的顺序分配和删除内存。这意味着你最后分配的内存对象将最先被删除。图 13.2 是堆栈内存的示意图。

​ 通常,过程、函数和方法调用使用栈传递参数及其返回值,以及声明在函数或方法中的局部变量。一旦例程调用结束,栈上的内存区域就会被释放。请记住,Object Pascal 默认使用寄存器调用约定,即尽可能在 CPU 寄存器而不是栈中传递参数。

图 13.2:栈内存区域的表示

​ 还要注意的是,为了节省时间,栈内存通常不会被初始化或清理。这就是为什么如果将一个整数声明为局部变量,然后读取它的值,却不知道它的值是多少。这就是为什么所有局部变量在使用前都需要初始化的原因。

​ 栈的大小通常是固定的,由编译过程决定。您可以在 Project | Options 的 linker 页面设置该参数。不过,默认值通常就可以了。如果你收到 "堆栈溢出 "的错误信息,很可能是因为有函数一直递归调用自己,而不是因为栈空间有限。Project | Information 对话框提供的另一条信息是初始栈大小。

13.1.3 堆

​ 堆是以随机顺序分配和回收内存的区域。这意味着,如果您按顺序分配了三个内存块,它们以后可能以任何顺序被销毁。堆管理器会处理所有细节,因此你只需使用底层的 GetMem 函数或调用构造函数来创建对象,系统就会为你返回一个新的内存块(可能会重复使用已丢弃的内存块)。Object Pascal 使用堆为每个对象、字符串文本、动态数组以及大多数其他数据结构分配内存。

​ 由于堆是动态的,因此堆是程序出问题最多的内存区域:

  • 每创建一个对象,都需要将其销毁。如果不这样做,就会发生 “内存泄漏”,除非反复发生,直到堆内存消耗殆尽,否则不会造成太大危害。
  • 每次销毁对象时,都必须确保不再使用该对象,而且程序不会再次销毁该对象。
  • 动态创建的任何其他数据结构也是如此,但Object Pascal语言运行时基本上是自动处理字符串和动态数组,所以你几乎不用担心这些问题。
  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值