为什么其他编程语言没有垃圾回收器?
为什么这些其他语言没有内置垃圾回收机制?为什么程序员需要负责垃圾回收?
为什么其他编程语言没有垃圾回收器?
为什么这些其他语言没有内置垃圾回收机制?为什么程序员需要负责垃圾回收?
不使用垃圾回收的原因:
直到1985-1990年左右才开发出真正高效的垃圾回收器。如果当时设计语言时考虑了效率,那么就不会有垃圾回收功能。例如:Ada、C、Fortran、Modula-2、Pascal。
Bjarne Stroustrup 认为更好的语言设计是使每个成本都显式,并且“不为你不使用的功能付费”。(请参阅他在第二届和第三届编程语言历史ACM会议上的论文。) 因此,C++ 没有垃圾回收功能。
一些研究型语言使用其他思路(如区域,高级类型系统)来明确、安全地管理内存。这些思路对于设备驱动程序等问题具有特殊优势,因为你可能无法负担分配内存,或者对于实时系统,内存成本必须非常可预测。
也有一些具有强类型但没有垃圾收集器的语言,这要么是因为它们的设计者不相信垃圾收集器,要么是因为他们相信在没有垃圾收集器的情况下能做得更好,或者是因为他们害怕额外的代码大小(例如,智能卡的Java - Javacard是无需垃圾收集器的,因为在只有8 kB代码和512字节RAM的环境中安装垃圾收集器是困难的)。
最后,在成千上万的编程语言中(我曾经听说过“自60年代以来每周设计一次”),有些是在夜深人静时谈论酒精过量的结果,因此不能认为所有编程语言的每个特性或非特性都是平衡理性思考的结果。
C#
,而.NET CLR绝对会执行自动垃圾回收。C++中所有现有的代码都使用显式内存管理,因此实现垃圾回收将是一个破坏性的变化;
同样地,C++程序员已经习惯了显式内存管理,因此垃圾回收并不是一个非常重要的功能;
好的垃圾回收算法相当新颖,而C++比它们早得多。垃圾回收是一种水平特性,语言设计者必须对规范进行重大(且复杂)的更改。简而言之,在现有语言中添加垃圾收集器比在从一开始就设计语言时更难。
Java运行在虚拟机上,.NET使用类似的东西,而C++处理本地代码。在前一种情况下,GC要容易得多。
C++经常用于需要在严格内存要求下运行的应用程序(即嵌入式系统),在这些情况下,显式内存管理是必需的。我想某种形式的“选择性”GC可以解决这个问题,但这对于语言设计者来说甚至更难实现。
这些是有限的资源,你希望它们在不再使用时尽快被释放,而不是完全不释放或者仅在进程退出时才释放。
在受GC影响的语言中(如Java),这些资源通常必须手动获取和释放。如果你想看看它有多么丑陋,请看看这个问题:
使用RAII习惯将使您编写可读性强的代码,没有任何泄漏,无论是内存还是其他方面。事实上,我无法记得自己曾经担心过内存分配/释放的时间,尽管我没有使用垃圾回收。
但我清楚地记得在2008年10月,我不得不解决Java中的资源泄漏问题,解决方案是如此丑陋,以至于令人厌恶。
为什么其他语言没有垃圾回收机制?
答案可能是:
C++更多地属于“没有必要”的部分。
GC可以成为C++ RAII的一个很酷的补充(请参见C ++中的垃圾回收 - 为什么?),但我绝不会用你的GC来交换我的RAII。
永远不会。
一些编程语言比较古老,例如C语言,最初是为比今天慢得多的机器上的系统编程而设计的。当时可能还不存在垃圾回收(也许Lisp除外?),即使有,设计师们也不想在程序员自己可以完成的情况下花费所有的CPU循环和内存开销来执行垃圾回收。由于那时的计算机性能远不如今天,软件也相对简单,因此程序员手动管理内存比在现在可能编写的更大型应用程序中更容易。
一个简单的事实是:并不存在银弹。垃圾回收并不能解决所有的内存/性能问题。
像C#和Java这样的现代语言具有垃圾回收功能,因为如果您不必担心内存管理,编写代码会更容易。而旧的语言则没有这个功能。此外,还有许多应用程序(例如在没有任何虚拟内存访问权限的嵌入式应用程序中运行),您需要精确地管理应用程序将使用多少内存,对于这些情况,C++等语言更合适。实时应用程序也可能限制您使用垃圾回收语言的能力,因为您需要完全控制应用程序在任何时候的响应速度。
C、C++、Java 和 C# 是在不同的时间点创建的(并按照这个顺序)。Java 和 C# 都有垃圾回收机制。
通常,最近开发的语言往往具有更好的内存管理支持,因为技术水平每次都会有所提高。
实际上,C和C++都有垃圾回收机制在这里。
但总的来说,C/C++社区从一开始就对许多成功的编程语言特性产生了厌恶情绪,这些特性在动态语言社区广泛使用,其中包括GC。我认为这种现象部分源于贝尔实验室的文化;你会发现一群核心、聪明、努力的人们,他们坚信自己知道得更好,不需要任何语言特性来降低缺陷率。这就是为什么C字符串仍然是一个噩梦般的安全漏洞,今天仍然造成着巨大的安全问题:因为一群贝尔实验室的黑客知道,他们可以编写安全的代码,即使API由剃刀和硝化甘油制成。完美的程序员不需要网络字符串,完美的程序员也不需要垃圾回收机制。可惜没有完美的程序员。自信很重要,但谦卑可以防止我们自我毁灭。
String
字段,则任一对象都可能知道何时不再需要“Fred”,但不应关心... - supercatWeakReference
这样的东西来强制String
表现为一种实体,否则对象(或其他人)是否正在使用相同的String
对象不确定。 除非某个可达引用路径指向它,否则字符串将在瞬间停止存在。GC不会销毁除那些仅由诸如弱引用之类的东西可访问的对象之外的对象; 相反,它回收不存在的对象曾经使用的内存。 - supercat