编译原理学习之运行时数据区的管理

来源:互联网 发布:瑞典帅哥成灾 知乎 编辑:程序博客网 时间:2024/06/08 08:41

存储单元分配策略

1、静态存储分配

•在编译时就可以完全为数据项目分配存储单元,称为静态存储分配。
•注:若一个程序设计语言不允许递归调用,而且不含有可变数组,则可使用静态存储分配策略。

2、动态存储分配

•在运行时才能进行数据存储单元分配,称为动态存储分配。
•注:
1)若某程序设计语言允许过程递归调用,而且允许使用可变数组,那么在编译时就不可能完全为其数据项目分配存储单元,必须采取动态存储分配策略。
•2)动态分配数据单元时一般使用:
–栈式存储分配
–堆式存储分配

(1)栈式存储分配

•运行时,每进入一个过程,就在栈顶为该过程分配一块数据区,一旦退出该过程,它所占的空间也退还给系统。

(2)堆式存储分配

•有些语言允许用户随时动态地申请和释放存储空间,但申请和释放之间不遵守先申请后释放或后申请先释放原则,故不能使用栈式存储分配,而是更复杂的动态分配策略。
•这种策略是:让运行程序持有一个大的存区(堆),在申请时从堆中取一块,释放时将一块存储区退还给堆。

栈式存储管理

1.允许过程(函数)递归调用的数据存储管理

•1、语言特点
允许过程(函数)的递归调用,但不允许定义嵌套的过程(一个函数在里一个函数里面定义),也不许使用可变数组。如C语言

活动记录就是高级语言里所说的内存单元
C语言的活动记录所含区段是:连接数据(包含老SP值(即前一活动记录的首地址;或称施调过程的数据区首地址)和返回地址(即调用语句的下一条指令的地址))、参数(形参)个数、形式单元(存放实参值或地址)、过程的局部变量(简单变量)、数组内情变量(数组)和临时工作单元(临时变量)。

2.嵌套过程语言的栈式存储管理

1、语言特点
既允许过程嵌套,也允许过程递归调用。
2、存储管理方式
1)根据嵌套过程语言的规定,由变量的最小作用域原则,一个过程可以引用包围它的任意外层过程所定义的变量和数组。所以,运行时过程必须知道它所有直系外层过程的最新活动记录的地址。
2)由于允许递归,过程活动记录的位置是动态变化的。因此,每个活动记录中必须设法记住直系外层的最新活动记录的位置,以处理递归。

堆式存储管理

对象:
–在高级语言中有些数据存储空间的请求与释放不再遵循后进先出的原则,而且是全局性的。
•对策:
–让运行程序持有一块专用的全局存储空间来满足这些数据的存储要求。这种存储空间就叫“堆”(heap)。
–堆通常是一片连续的足够大的存储区,当需要时,就从堆中分配一小块存储区;用完就及时退还给堆

堆式存储管理技术

1、固定长块管理
•方法:
–把堆空间分成许多固定长的块,每块的第一个字用作指示器,将所有未用块链接起来,形成一张可利用表。
–当堆管理程序收到请求分配空间时,就查询该表,并将一块空白块的首指示器送给申请者,然后修改此表。
2、可变长块管理
•申请分配空间时,堆管理程序从可利用表中查到一个未用块,若该块大于所需空间,就将它分成两部分,等于申请空间的一部分和剩余部分;这样下去留在可利用表中的块越来越小,最后形成无法用的外部碎片。
•若查到的块只比申请空间大一点,就不再分开,整个给申请者使用,此块中用不到的那部分也无法给别人用,就是内部碎片。
•注:这两种碎片很多时,碎片的总和大于申请空间,但无法分配给申请者。故可变长块管理主要考虑如何减少碎片的影响。
3、按块长不同分为若干集合
•方法:把整个堆空间分为若干集合,每个集合中块长是相等的,并把它们链接在一起。当申请m个长度为n的块时,就到块长为n或稍大于n的集合中去查找可利用块。若该集合中由m个这样的块,则满足申请;若没有m个,则从块长较大的集合中取一块或多块,把它们分成相等的两块然后再分配。
•注:优点:减少搜索时间,容易实现块合并;
•缺点:会使内部碎片增加。
声明:
以上内容引自东南大学编译原理课件

0 0