当前位置: 首页 > news >正文

(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语言运行时基本上是自动处理字符串和动态数组,所以你几乎不用担心这些问题。

相关文章:

  • Android Audio基础——AudioFlinger回放录制线程(七)
  • 【NUCLEO-G071RB】007——IWDG-喂狗
  • 网站策划是什么
  • 专注于运动控制芯片、运动控制产品研发、生产与销售为一体的技术型芯片代理商、方案商——青牛科技
  • mac 系统正确安装nvm
  • 山东大学软件学院项目实训-创新实训-基于大模型的旅游平台(十九)- JUC(5)
  • 在Visual Studio Code和Visual Studio 2022下配置Clang-Format,格式化成Google C++ Style
  • linux的用户管理
  • 前端 MVC 分层的实践
  • 公司废弃的2014年群晖 DS215J 被我打包回家了,试玩一下
  • 世界上首位AI程序员诞生,AI将成为人类的对手吗?
  • Vue.js - Vue 的安装 以及 常用的 Vue 指令 【0基础向 Vue 基础学习】
  • Pytorch-08 实战:手写数字识别
  • 力扣刷题---3146. 两个字符串的排列差
  • 开源内网穿透神器:中微子代理(neutrino-proxy)实现内网穿刺
  • 时间复杂度分析经典问题——最大子序列和
  • Angular 响应式表单之下拉框
  • Java 9 被无情抛弃,Java 8 直接升级到 Java 10!!
  • Java|序列化异常StreamCorruptedException的解决方法
  • JSDuck 与 AngularJS 融合技巧
  • mac修复ab及siege安装
  • PHP 7 修改了什么呢 -- 2
  • spark本地环境的搭建到运行第一个spark程序
  • vue总结
  • Webpack 4 学习01(基础配置)
  • 聚类分析——Kmeans
  • 聊聊redis的数据结构的应用
  • 前端技术周刊 2018-12-10:前端自动化测试
  • 全栈开发——Linux
  • 容器服务kubernetes弹性伸缩高级用法
  • 适配iPhoneX、iPhoneXs、iPhoneXs Max、iPhoneXr 屏幕尺寸及安全区域
  • 通过npm或yarn自动生成vue组件
  • 我从编程教室毕业
  • 学习ES6 变量的解构赋值
  • 容器镜像
  • 如何正确理解,内页权重高于首页?
  • ​LeetCode解法汇总2670. 找出不同元素数目差数组
  • ​如何使用ArcGIS Pro制作渐变河流效果
  • #NOIP 2014#day.2 T1 无限网络发射器选址
  • #ubuntu# #git# repository git config --global --add safe.directory
  • #经典论文 异质山坡的物理模型 2 有效导水率
  • $Django python中使用redis, django中使用(封装了),redis开启事务(管道)
  • (2024,Vision-LSTM,ViL,xLSTM,ViT,ViM,双向扫描)xLSTM 作为通用视觉骨干
  • (4)通过调用hadoop的java api实现本地文件上传到hadoop文件系统上
  • (zhuan) 一些RL的文献(及笔记)
  • (超简单)使用vuepress搭建自己的博客并部署到github pages上
  • (附源码)ssm高校实验室 毕业设计 800008
  • (转)关于如何学好游戏3D引擎编程的一些经验
  • (轉貼)《OOD启思录》:61条面向对象设计的经验原则 (OO)
  • **Java有哪些悲观锁的实现_乐观锁、悲观锁、Redis分布式锁和Zookeeper分布式锁的实现以及流程原理...
  • .\OBJ\test1.axf: Error: L6230W: Ignoring --entry command. Cannot find argumen 'Reset_Handler'
  • .360、.halo勒索病毒的最新威胁:如何恢复您的数据?
  • .NET CF命令行调试器MDbg入门(一)
  • .NET Framework 4.6.2改进了WPF和安全性
  • .NET Windows:删除文件夹后立即判断,有可能依然存在