漫画 | 垃圾回收实在是太垃圾了!

本文回顾了从Lisp到现代垃圾回收(GC)的发展历程,介绍了标记-清除、复制和引用计数算法,以及它们的优点与挑战。重点讲述三位GC算法大师的贡献,以及后续标记-压缩算法的诞生。

1960年,人工智能之父 John McCarthy 在麻省理工大学做了一次重要演示


Lisp的担心很快就变成了现实

垃圾回收虽然在卖力工作,可是系统还是恢复不了。

在编程的世界中,内存分配每时每刻都在发生,从底层来讲,可以分为三类。

而Lisp中所有的数据都是“表”(List),都是在堆中动态分配的,如果它不支持GC,程序员管理表(List)估计就会疯掉。

为此, John McCarthy于1960年发表了一篇论文,提出了标记-清除算法。

算法分为两个阶段, 第一个阶段是标记, 从一个GC root集合出发,沿着“指针”找到所有活动对象

到了清除阶段,只需要把那些没有被标记的对象删除,释放空间就行。

标记-清除算法非常简单,容易实现,现在垃圾收集算法都是它的思想的延续。

仅此一点,McCarthy就可以成为GC算法之父。

可是标记-清除算法也有两个要命的缺点:分配速度慢,容易产生碎片。

为了解决这个问题, 1963年, 另外一位人工智能之父”的Marvin L. Minsky提出了著名的复制算法。

Minsky 的复制算法需要把整个空间平均分成两部分, 先在From空间进行分配,当From空间被占满,GC将活动对象复制到To空间, 复制完成后, From和To进行互换。

复制算法的第一步也是标记,但是找到活动对象以后,直接复制到另一半空间,所以能在较短时间内完成GC。

并且每次复制的时候,对象都会集中,避免碎片。

标记-清除算法和复制算法优缺点都非常明显。

1960年, George E. Collins独辟蹊径,提出了一个新的GC算法:引用计数

当时Collins可能没有注意到,引用计数法有个缺点,就是它不能回收“循环引用”

至此, 垃圾收集技术的三大算法已经集齐,GC根本性的内容已经完成。后人只是在GC大厦上修修补补罢了。

三位GC大佬说得没错,1970年出现的标记-压缩算法就是标记-清除和复制算法结合的产物。

标记压缩算法工作起来是这样的:

标记-压缩看起来和复制算法很像,但是算法实现要复杂得多

后来人们又发现:大部分对象的生存期限很短,生下来不久就变成垃圾

于是把对象进行分代,对不同的分代实施不同的垃圾收集算法

几十年过去了, 垃圾回收技术不断完善, 计算机的性能也越来越高。 

Lisp曾经遭遇的GC尴尬不会再出现了,GC逐渐成了编程语言的标配。 

当然, 还有些编程语言在坚守,因为他们承担着更重要的使命。

GC把程序员从内存管理中解放出来,世界上没有免费的午餐,付出的代价就是多了虚拟机/解释器这一层额外的开销。

也许有这么一天,程序员既不需要操心内存空间的管理,又可以充分发挥硬件的效率,期望这一天能够来临。 

嗯, 这一天其实已经来了,它就是Z语言, 参见《Z语言传奇

(完)

点击下方图片,查看更多文章吧 !

### C/C++ 学习的困难与挑战 #### 复杂的语言特性 C++ 基于 C 语言扩展了许多高级特性,如类、对象、继承、多态、模板以及异常处理等。虽然这些功能增强了编程灵活性和效率,但对于初学者来说却增加了复杂度[^1]。 ```cpp class Example { public: void show() const; private: int value_; }; ``` 上述代码展示了定义一个简单的 `Example` 类的过程,在其中包含了访问控制符(`public`, `private`)、成员函数声明及其常量限定符(`const`)等内容,这些都是新手难以立即掌握的知识点之一。 #### 容易出错的手动内存管理 手动分配和释放动态内存是 C 和 C++ 的一个重要方面,但这同样也是最容易引发错误的地方。不正确的指针操作可能导致严重的运行时崩溃或未定义行为: ```cpp int* ptr = new int(10); // 使用完毕后忘记删除 delete ptr; // 如果遗漏此句,则会造成内存泄漏 ``` 这种情况下如果程序员疏忽了 `delete` 操作就会造成资源浪费甚至应用程序不稳定等问题。 #### 难以调试的低级错误 由于缺乏自动垃圾回收机制和其他现代语言的安全保障措施,编写高质量且无误的 C 或者 C++ 程序往往需要更细致入微的关注细节并具备丰富的经验才能有效避免潜在问题的发生。例如缓冲区溢出攻击就是一种常见的安全隐患形式。 #### 社区趋势的影响 尽管 Russinovich 认为应当停止使用 C/C++ 创建新项目而推荐采用 Rust 来提高安全性与可靠性;但是值得注意的是这一观点并不代表整个行业都已达成共识。对于那些已经熟练掌握了这两种经典编程语言的人来说,继续沿用它们仍然是合理的选择[^3]。
评论 29
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值