一个对象拥有其语义价值的区域<其作用域
当一个变量将不再被使用,那它应该被理想的回收机制回收。但现实是我们仅当一个变量离开了其作用域,或变成不可访问,才考虑回收。
然而,作用域规则有其优点:1.可以一次性考虑一组语义上存在关系的变量,并能对其进行成批回收。
相对于显式的作用于规则,隐式的自动垃圾回收将尝试提前回收作用域周期较长的变量。
但另一方面,我们需要更灵活的引用环境规则,来获得更丰富的语义表述。
语言设计的目标:高级特征——高抽象级别
机器无关性:不依赖于特定指令集
名字:有效标识符(词法分析,扫描器),用来表示变量 ,常量,操作,类型等。完成了一次抽象。
低级 高级
地址 标识符
抽象是一个过程,,将一个名字与一个程序片段相关联,封装成一个接口。
子程序:控制抽象。类:数据抽象。
抽象隐藏了细节,减少了概念的复杂性。我们将要看到的,是复杂的实现细节,以及判断在抽象中暴露哪些细节,隐藏哪些
在3-8章中用对象表示可以有名字的东西
3.1约束时间:名字与事物的约束
约束时间:实现决策的期间。在各个阶段确定一部分语义,消除不确定性
语言设计时:控制流程,内部数据结构,类型构造器等语言语义
语言实现时:类型精度,IO连接到操作系统,栈堆组织方式,异常处理
编写语言时:算法,数据结构,名字
编译时:高级结构映射到机器代码,静态定义数据在内存中布局
连接时:标准子程序库或其他模块连接
装入时:为对象选择机器地址,虚拟地址翻译到物理地址计算映射
运行时:值与变量的约束。程序启动时,模块入口时,加工时(首次声明),子程序调用时,分程序进入时,语句执行
术语:静态,动态
编译器确定全局变量在内存中的分布,确定局部变量的地址偏移(帧指针)。布局&高效访问
3.2为对象分配与释放存储空间的机制,对象与名字的生存期
命名&约束
名字引用对象
关键事件:对象,名字 创建,引用,失活激活,撤销
生存期:创建——撤销(
对象的名字的不重合:悬空引用,内存泄漏
作用域:进入,退出(空洞),失活激活,结束
生存期对应于三种主要的存储分配机制,用于管理!对象!空间
静态对象:绝对地址,全局
栈对象:先进先出分配释放,对应于子程序调用与退出
堆对象:任意时间,要求更通用的存储管理算法
1.静态分配:全局变量,语句翻译成的指令,子程序在调用间保持值的局部变量,常量字面量(小的保存在指令中,大的保存在存储区),
编译器生成的:表格,支持运行时的例程:调试,动态类型检查,废料收集,异常处理
其中执行时不该改变的:指令,常量,运行时表格,分配受保护的只读区,写操作导致处理器中断
编译时常量:常量,常量调用内部函数&算术运算符,
加工时常量:依赖于程序具体运行,加工后不变
???不会同时出现对同一子程序的多个活动状态的调用——静态分配局部变量
编译器负责保存:加工时常量,局部变量?子程序相关信息:参数值&返回值寄存器或内存,临时量:寄存器,簿记信息:返回地址,动态链,寄存器内容,错误信息
2.栈
递归结构:局部变量不能静态分布——一个变量可以同时拥有多个实例个数
嵌套结构:容易分配栈空间
子程序实例:在栈上的帧中,包含:参数,返回值,局部变量,临时值,簿记信息
栈维护子程序的调用序列:调用者,前序,后序代码组合
编译器不能确定帧栈地址,(静态)确定对象在帧内的偏移(寄存器,帧指针)
局部变量,临时值,簿记信息:帧负偏移
参数,返回值:帧正偏移(调用方帧内)
当前活动子程序数目<<all子程序数目,栈中分配好于静态
栈指针:第一个未用位置
帧指针:帧中已知未知
3.堆
大小可变的对象:赋值与更新操作
堆空间管理:速度与空间的权衡
内部碎片:供>求
外部碎片:max供<求<all供
*表:未使用空间的链接表
最先适配:
最佳适配:搜索开销 ,较少的外部碎片
供>>求时,两种算法都切块
合并相邻未分配块
维护单一*表:分配的代价与*块数目,线性相关
为不同大小的块维护不同的*表,将堆划分成存储池
划分:静态,动态:伙伴系统2的乘幂,斐波那契堆,及时合并
外部碎片问题:碎片数量随时间递增,max块递减
移动已分配块,堆的紧缩
废料收集
手动:识别对象的生存周期的结束。悬空引用,流失存储
自动:边际复杂性降低
3.3作用域规则
约束的作用域:约束起作用的正文区域,大多为静态确定
3.5别名,重载,多态
3.6宏扩
展