为什么其他语言没有类似于Java垃圾收集器的自动垃圾收集?

时间:2010-03-15 02:43:26

标签: c# java c++ c garbage-collection

没有垃圾收集器的其他语言背后的原因是什么?

为什么这些其他语言没有内置垃圾收集?为什么程序员有责任收集?

10 个答案:

答案 0 :(得分:20)

没有垃圾收集的原因:

  • 直到1985年至1990年左右才开发出真正高效的收藏家。在此之前设计的语言,如果效率是目标,则没有垃圾收集。示例:Ada,C,Fortran,Modula-2,Pascal。

  • Bjarne Stroustrup认为更好的语言设计可以使每一项费用明确,并且“不为你不使用的功能付费”。 (参见他在第二届和第三届ACM会议上关于编程语言历史的论文。)因此,C ++没有垃圾收集。

  • 一些研究语言使用其他想法(区域,花式类型系统)来明确但安全地管理内存。这些想法特别适用于设备驱动程序,您可能无法负担分配的问题,或实时系统,其中内存成本必须非常可预测。

答案 1 :(得分:5)

“其他语言” - 这个问题标记为C#,.NET CLR绝对 执行自动垃圾回收。

我可以想到C ++没有它的几个原因:

  • C ++中的所有现有代码都使用显式内存管理,因此实现垃圾收集将是一个重大变化;

  • 出于同样的原因。 C ++程序员已经习惯于显式内存管理,因此垃圾收集并不是一个重要的功能;

  • 好的垃圾收集算法是相当新的,而C ++在它们之前就已经相当多了。垃圾收集是一种水平功能,语言设计者必须对规范进行重大(和复杂)更改。简而言之,将垃圾收集器连接到现有语言比从一开始就将其设计为语言更困难,就像使用.NET和Java一样。

  • Java在虚拟机中运行,.NET使用类似的东西,而C ++处理本机代码。在前一种情况下,GC更容易推理。

  • C ++通常用于需要在严格的内存要求(即嵌入式系统)下运行的应用程序,在这些情况下,显式内存管理是必需的。我想某种“选择加入”GC可以解决这个问题,但这对语言设计者来说甚至可以更加更难

答案 2 :(得分:5)

硬件没有垃圾收集器( 某些硬件对转发指针有一些基本的支持,这是一个在构建一些垃圾收集器时很有用的功能,但这远不是“硬件中的GC” “)。相应地,装配没有GC。汇编是一种“编程语言”(虽然是最接近裸机的一种),所以他们就是这样:在广泛的现有编程语言中,有些人没有GC。

事实上,高效 GC并不容易实现。很好的算法已经很长时间了。更重要的是,大多数优秀的GC算法都很好,因为它们执行一些复杂的操作,例如在RAM中移动数据元素;这对于“实时GC”来说是必要的,它可以保证分配所花费的最长时间(当存在碎片时,您无法获得这样的保证,并且如果不在RAM中移动对象,则无法避免碎片)。移动对象时,必须自动调整指向该对象的所有指针,如果编程语言提供强大的,不可避免的类型,则只能 。例如,使用C或C ++无法做到这一点。在C中,打印出编码指针值的字节是合法的,然后让用户键入它们。 GC移动对象时无法改变用户的大脑......

所以在实践中,没有强类型的语言是无GC的。这包括C,C ++,Forth,各种汇编扩展语言......这并不妨碍某些人为这些语言编写GC实现,例如Hans Boehm's GC for C and C++。但这确实意味着,就语言标准而言,GC可能会以名义上“合法”的(奇怪的)程序失败。

还有一些类型很强但没有GC的语言,或者是因为他们的设计师不相信它,或者认为没有它们可以做得更好,或者从额外的代码大小中畏缩(例如,Javacard,用于智能卡的Java) ,GC是无GC的,因为在具有8 kB代码和512字节RAM的环境中安装GC 容易)。

最后,在设计的数千种编程语言中(“自六十年代以来每周一次”,我曾被告知),有些是酒精过多导致的深夜对话的结果,所以它不能假设所有编程语言的每个特征或非特征都是平衡理性思考的结果。

答案 3 :(得分:3)

有些语言陈旧。例如C,最初设计用于比现在慢得多的机器上的系统编程。垃圾收集可能当时不存在(好吧,也许是Lisp?),即使它确实如此,设计人员也不希望在程序员自己完成垃圾收集时花费所有CPU周期和内存开销。而且由于机器的功能不那么强大,软件也更简单,因此程序员手动管理内存比在今天可能编写的更大的应用程序中更容易。

答案 4 :(得分:3)

人们已经回答了你的问题,但是,你的问题还有一个隐藏的断言,即“垃圾收集是所有问题的解决方案”,我想讨论这个断言......

GC不是处理内存的唯一方法

至少有三种处理内存分配的方法:

我们同意“手动”实际上可能很麻烦和丑陋。现在,你应该注意到即使使用GC,也有一些不正确的方法来泄漏内存。

GC无法处理资源泄漏

除了内存之外,程序中还有很多有限的资源:

  • 文件句柄
  • 其他操作系统处理
  • 网络连接
  • 数据库连接

那些是你想要在不再使用时被释放的有限资源,而不是“根本不用”,甚至“当进程退出时”。

这些资源通常必须在GC驱动的语言(即Java)中手动获取和取消。如果你想看看它有多丑,请看看这个问题:

RAII in Java... is resource disposal always so ugly?

RAII确实处理内存和资源泄漏

使用RAII习惯用法可以编写可读代码,而不会出现任何泄漏,内存或其他问题。事实是,我记不清楚,编写C ++代码时,我担心内存分配/释放,尽管事实上我没有使用垃圾收集。

但我清楚地记得,在2008年10月,我不得不处理Java中的资源泄漏问题,解决方案太难看了,令人作呕。

结论

  

没有垃圾收集器的其他语言背后的原因是什么?

答案可能是:

  • 因为当时GC不够有效
  • 因为GC不是所有资源泄漏的解决方案
  • 因为没有必要。

C ++更多地出现在“没有必要”部分。

GC对C ++的RAII来说是一个很好的奖励(见Garbage Collection in C++ -- why?),但是我无法将你的RAII换成你的GC。

自从。

答案 5 :(得分:2)

一个简单的事实是没有银弹。 GC尚未解决所有内存/性能问题。

答案 6 :(得分:1)

如果你不知道为什么,这是因为金钱。在早期,计算机价格昂贵,程序员便宜。现在它的180度不同 - 电脑很便宜而且程序员很贵。 GC需要一点CPU来完成他的工作。

此外,大多数GC有时需要冻结程序才能执行全扫描。在实时软件 - 工业监控,股票市场等 - 这不是一个选择。有时客户也可以在我共同开发的应用程序中看到它(ASP.NET网站有时会冻结一分钟左右)。

另一个原因 - 没有人是完美的,GC可能会有一些泄漏。如果你仔细阅读一些不太可能的非GC语言。

答案 7 :(得分:0)

更多现代语言如C#和java都有垃圾收集,因为如果您不必担心内存管理,编写代码会更容易。较旧的语言没有。还有许多应用程序(例如,运行时无需访问虚拟内存的嵌入式应用程序),您需要准确管理应用程序将使用多少内存,对于这些语言,如C ++更合适。实时应用程序也可能限制您使用垃圾收集语言的能力,因为您需要完全控制应用程序随时响应的速度。

答案 8 :(得分:0)

C,C ++,Java和C#是在不同的时间点(按此顺序)创建的。 Java和C#都有垃圾收集。

通常,最近开发的语言往往会更好地支持内存管理,因为每次都有先进的技术发展。

答案 9 :(得分:0)

实际上有一个用于C和C ++的GC here

但总的来说,C / C ++社区从第一天就开始厌恶学习动态语言社区中广泛使用的许多成功的编程语言功能,从GC开始。在某种程度上,我认为这种现象来自贝尔实验室的文化;你有一堆硬核硬驾驶鞭子聪明的人,他们相信他们知道的更好,并且他们不需要任何语言功能来降低缺陷率。这就是为什么C字符串是一个噩梦般的安全漏洞,仍然在今天造成巨大的安全问题:因为一群贝尔实验室的黑客 知道 ,只知道,他们甚至可以编写安全的安全代码虽然API是用剃刀刀片和硝酸甘油制成的。完美的程序员不需要netstrings,完美的程序员不需要GC。太糟糕了,没有完美的程序员。信心很重要,但谦卑使我们不会摧毁自己。