一片自留地 斯坦福 CS143(编译原理)内存管理

magicyang · 2021年03月17日 · 1206 次阅读

前面一章介绍了寄存器申请。
这一章节介绍内存的管理。

内存管理概述


c++ 在 c11 之后引入动态指针后,稍微有些改善,但是相对而言,c/c++ 可以通过各种指针来绕过包括类型检查等各种限制,灵活底层的同时也确实一不注意就泄漏了。
从历史可以看到,到上世纪 90 年代,java 开始真正广泛使用,内存自动管理回收的技术才成为主流。

创建对象的回收理念:

创建后不使用的对象可以释放:

reachable 和 garbage 的定义:

这里举例说明了 reachable 和 unused 的区别。

如这里到 GC 的 B 点,是 reachable 的也是 unused 的,这里不会被回收。

回顾一下函数调用的堆栈和 AR(activation record) 结构:

在内存回收的过程中会使用到 AR 的结构
例子:

内存回收的步骤:

mark & sweep

实现方法:

make phase 伪代码实现:

sweep phase 实现:

sweep phase 伪代码:

操作例子:

实现中需要注意的点:

还是那句话,所有的工程到了系统这层,都是各种 tricky。

pointer reversal:


具体怎么操作就不说了。
这里的指针反转是用来标记 object 的 remarkable,当深度优先遍历结束之后,需要把反转指针擦除。

mark & sweep 总结


这也就是为什么 c/c++ 需要 memset 初始化的原因了。

stop & copy

预先分配一段空间,用于资源的 copy。

具体实现步骤:



伪代码:

stop & copy 总结:


由于资源 copy 的速度相对较快,所以这是最快速的方法。
c/c++ 由于有指针的操作,无法判断什么存储空间中哪些是指针哪些是数据,所以无法直接 copy.

c/c++ 有保守 copy 的方法

但是还是无法避免部分内容不能 copy 的问题。

引用计数

实现方案:

优缺点:

缺点 1,是如果有环路,会一直递归。
缺点 2,如果是简单操作,那么 count 计数的指令也会占用较大的资源。
但是这个方法还是很好的,很多语言都是用了引用计数来回收,如 java.

内存回收总结:



ps:在实时系统和并行系统中还会有其他的算法来对应的支撑系统特性。

暂无回复。
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册