C#和Java中的垃圾收集有什么根本区别?

时间:2010-08-13 15:47:52

标签: c# java garbage-collection

我最近从“高级”开发人员/同事那里得到了一些关于C#垃圾收集器的非常错误的声音建议,例如......

  • “你需要使用析构函数 在C#到处都是因为垃圾 收藏家不能依赖。“

  • “C#垃圾收集器不能 想到了Java垃圾 集电极”。

这听起来非常可疑,据我所知,C#和Java垃圾收集器之间的区别如下......

  • C#是一代垃圾 收集器,Java是并发标记 在1.6中横扫,G1是新的 默认(世代)垃圾 采用Java 7的收藏家 自~1.6.21以来一直是可选的。目前 据我所知
  • C#作为一种语言有能力 手动处理那些对象 实施IDisposable。 Java必须 总是使用垃圾收集, 虽然有些框架如SWT 要求你手动调用方法 在底层发布内存 本地代码。

我意识到Java和C#只是语言而垃圾收集器是运行时的一个组件,但是对于这种情况,我特别谈到了Sun / Oracle JVM和Microsoft .NET Runtime。

有人有反馈吗?

3 个答案:

答案 0 :(得分:16)

从广义上讲,你给出的建议很多。

C#和Java都有GC试图优化大量小对象的快速恢复。它们旨在解决同样的问题,它们以稍微不同的方式进行,但作为用户,使用它们的方法中的技术差异很小,甚至对大多数用户来说也不存在。

IDisposable与GC无关。这是命名方法的标准方法,否则将被称为closedestroydispose等,并且通常在Java中称为。 Java 7提议添加与using关键字非常相似的内容,这些关键字可以调用类似的close方法。

C#中的“析构函数”指的是终结符 - 这是故意混淆C ++程序员的。 :) CLR规范本身将它们称为终结器,就像JVM一样。

Java和C#/ CLR有很多种不同的方式(用户值类型,属性,泛型以及称为Linq的整个相关功能系列),但GC是一个可以开发大量软件的领域在你需要担心它们之间的差异之前。

答案 1 :(得分:3)

他倒退了。您需要在C#中使用析构函数,除非重要。如果你确实使用它们,你应该调用SuppressFinalize(),如果你知道对象处于不再需要析构函数代码的状态(通常是因为在调用IDisposable.Dispose()时发生了同样的清理。如果一个对象有一个析构函数并且没有调用SuppressFinalize,那么它会活得更长(这样就可以调用析构函数)。

垃圾收集器当然可以依赖。不能依赖于调用析构函数,或者在一定的时间内调用析构函数,但这不是它不可靠的问题,而是收集垃圾的可靠性问题,这是它的工作! / p>

我对Java垃圾收集器了解不多,我毫不怀疑他说当你得到更好的细节时他们不能像对方一样被认为是对的,尽管我希望为了Java编码器的缘故,大多数时候它可以被认为是.NET的一部分 - 根本就没有想到它,通常你不需要。

答案 2 :(得分:2)

我担心你的同事是不正确的,但不要相信我的话。让我们有一个链接巨星!

以下是关于GC的一些好文章: http://msdn.microsoft.com/en-us/magazine/bb985010.aspx http://msdn.microsoft.com/en-us/magazine/bb985011.aspx

另外,Maoni的WebLog有一些很棒的东西(也会带给你最新的,因为上面的文章已经很老了): http://blogs.msdn.com/b/maoni/

此外,就在本周,Raymond Chen正在撰写关于GC的系列文章: http://blogs.msdn.com/b/oldnewthing/archive/2010/08/13/10049634.aspx

以下是关于使用Dispose和Finalization的一个很好的讨论: http://www.bluebytesoftware.com/blog/2005/04/08/DGUpdateDisposeFinalizationAndResourceManagement.aspx