编译原理
  • 编译原理
  • 一些简答题
  • 绪论
    • 编译器简介
    • 程序设计语言
    • 静态与动态
    • 参数传递机制
  • 词法分析
    • 词法单元、模式、词素
    • 串和语言
    • 正则表达式
    • 状态转换图
    • 不确定有穷自动机NFA
    • 确定有穷自动机DFA
    • 算法:正则表达式转NFA
    • 自动机到词法分析器
  • 语法分析
    • 语法分析器
    • 上下文无关文法
    • 二义性和左递归
    • 递归下降语法分析
    • 算法:求解FIRST集和FOLLOW集
    • 算法:LL(1)
    • 自底向上语法分析
    • 移入-归约语法分析
    • 算法:LR(0)
    • 算法:SLR(1)
    • 算法:LR(1)
    • 算法:LALR
    • LR分析器和LALR分析器
  • 语法制导
    • 语法制导定义(SDD)
    • 综合属性和继承属性
    • 语法树上的SDD求值
    • 依赖图
    • L属性的SDD
    • 类型
    • SDD的应用
  • 中间代码生成
    • 三地址代码
    • SSA(静态单赋值)
    • 类型和声明
    • 表达式的翻译
    • 类型检查
    • 控制流
    • 回填
  • 运行时刻环境
    • 存储组织
    • 栈式分配
    • 栈中非局部数据的访问
    • 堆管理
    • 垃圾回收
  • 代码生成
    • 代码生成器的设计
    • 目标语言
    • 目标代码中的地址
    • 基本块和流图
    • 基本块的优化
Powered by GitBook
On this page
  • 垃圾回收器的设计目标
  • 可达性
  • 改变可达对象集合的操作
  • 垃圾回收方法
  • 基于引用计数的垃圾回收器
  • 循环垃圾
  • 基于跟踪的垃圾回收
  • 标记-清扫式垃圾回收
  • 标记-复制式垃圾回收
  • 标记-整理式垃圾回收
  • 垃圾回收算法比较
  • 分代式垃圾回收
  1. 运行时刻环境

垃圾回收

垃圾:广义上不需要再被引用的数据;狭义上不能被引用(不可达)的数据。

垃圾回收:自动回收不可达数据的机制,接触了程序员的负担。

垃圾回收器的设计目标

基本要求:语言必须是类型安全的,保证回收器能够知道数据元素是否为一个指向某内存块的指针。(静态类型ML、动态类型Java),类型不安全的语言(C/C++)。

性能目标:总体运行时间不显著增加应用程序的总运行时间;空间使用最大限度地利用可用内存;停顿时间当垃圾回收机制启动时,可能引起应用程序的停顿,这个停顿应该比较短(很少在实时应用中使用);程序局部性改善空间局部性和时间局部性。

可达性

可达性就是指一个存储块可以被程序访问到。根集:不需要指针解引用就可以直接访问的数据。

根集的成员都是可达的;对于任意一个对象,如果指向它的一个指针被保存在可达对象的某字段或数组元素中,那么这个对象也是可达的。

性质:一旦一个对象变得不可达,它就不会再变成可达的。

改变可达对象集合的操作

  • 对象分配:返回一个指向新存储块的引用

  • 参数传递和返回值

  • 引用赋值:u=v ,v的引用被复制到u中,u中原有引用丢失;(可能)使u原来指向的对象变得不可达,并递归使更多对象变得不可达。

  • 过程返回:活动记录出栈,局部变量消失;根集变小,使一些对象变得不可达。

垃圾回收方法

  • 关注不可达:跟踪相关操作,捕获对象变得不可达的时刻,回收对象占用的空间

  • 关注可达:在需要时,标记出所有可达对象,回收其他对象

基于引用计数的垃圾回收器

每个对象有一个用于存放引用计数的字段,并按如下方式维护:

  • 对象分配:引用计数设为1

  • 参数传递:引用计数+1

  • 引用赋值:u=v ,u指向的对象引用减1,v指向的对象引用加1

  • 过程返回:局部变量指向对象的引用计数减1

如果一个对象的引用计数为0,在删除对象之前,此对象中各个指针所指对象的引用计数减1

特点:开销较大,但不会引起停顿

循环垃圾

三个对象相互引用,没有来自外部的指针,又不是根集成员,都是垃圾,但是引用计数都大于0。

基于跟踪的垃圾回收

标记-清扫式垃圾回收

一种直接的、全面停顿的算法,分成两个阶段:

  • 标记:从根集开始,跟踪并标记出所有的可达对象

  • 清扫:遍历整个堆区,释放不可达对象

如果把数据对象看作节点,引用看作有向边,那么标记的过程实际上是从根集开始的图遍历过程。

标记-复制式垃圾回收

目标:只处理可达对象(减少回收时间),将可达对象安排到一起(减少内存碎片)。

堆空间被分为两个半区,应用程序在某个半区内分配存储,当充满这个半区时,开始垃圾回收。回收时,复制可达对象到另一个半区(需修改引用地址)。回收完成后,两个半区角色对调。

缺点是一般预留区域的内存无法使用。

标记-整理式垃圾回收

对可达对象进行重定位可以消除存储碎片:

  • 与标记-复制法将对象移动到预留另一半区不同,标记-整理法把可达对象移动到堆区的一端,另一端则是空闲空间

  • 空闲空间合并成单一块,提高分配内存时的效率

垃圾回收算法比较

  • 标记- 清扫式垃圾回收:回收效率不高,容易造成碎片

  • 标记-复制式垃圾回收:只需遍历可达对象,管理区域大部分对象为垃圾对象时效率高(只需移动少量可达对象),反之则效率低

  • 标记-整理式垃圾回收:将可达对象移动到堆区的一端,需遍历整个区域;管理区域内大部分对象为可达对象时效率高(经过之前的整理,大部分对象已经到位),反之则效率低。

分代式垃圾回收

对象生存周期特征:大多数对象刚创建不久后就不再使用(短命);存在时间越长的对象,通常被回收的几率越小(命硬)。

根据生存周期,对对象分代管理。新创建的对象均放入年轻代区域(从幼年期开始),年轻代空间不足时,对该区域进行回收(标记-复制,因为垃圾比较多);熬过回收的对象移入下一区域(进化);老年代空间不足时,对该区域进行回收(标记-整理,因为垃圾比较少)。

Previous堆管理Next代码生成器的设计

Last updated 4 months ago