最近,我从一位“高级”开发人员/同事那里得到了一些关于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 JVM。
有人有反馈吗?
3条答案
按热度按时间v1l68za41#
总的来说,给你的建议是一派胡言。
C#和Java都有GC,试图优化大量小对象的快速恢复。它们旨在解决相同的问题,它们以略微不同的方式完成,但作为用户,您使用它们的方法的技术差异是最小的,甚至对大多数用户来说是不存在的。
IDisposable
与GC本身无关。这是一种标准的方法命名方式,否则将被称为close
,destroy
,dispose
等,并且在Java中经常被称为。Java 7中有一个建议,添加一些非常类似于using
关键字的东西,它将调用类似的close
方法。C#中的“析构函数”指的是终结器--这是故意用来迷惑C++程序员的。:)Java规范本身称它们为终结器,就像JVM一样。
Java和C#/JavaScript有很多不同之处(用户值类型、属性、泛型和被称为Linq的整个相关特性家族),但是GC是一个可以在你需要担心它们之间的差异之前开发大量软件的领域。
k97glaaz2#
他在析构函数上落后了。在C#中你需要不使用析构函数,除非是至关重要的。如果你使用它们,如果你知道对象处于不再需要析构函数代码的状态,你应该调用SuppressFinalize()(通常是因为在调用IDisposable.Dispose()时发生了同样的清理)。如果一个对象有一个析构函数,并且还没有调用SuppressFinalize,那么它将存活更长时间(这样它就可以调用该析构函数)。
垃圾收集器当然是可以依赖的。不能依赖它来调用析构函数,或者在一定的时间内这样做,但这不是它不可靠的问题,而是它在收集垃圾时可靠的问题,这是它的工作!
我不太了解Java垃圾收集器,我毫不怀疑他说的对,当你深入到更细的细节时,它们不能被认为是彼此,尽管我希望为了Java编码者的缘故,它可以像.NET一样被认为是大多数时候-也就是说根本不去想它,通常你不必这样做。
2skhul333#
恐怕你的同事是不正确的,但不要相信我的话。让我们有一个链接fest!
以下是一些关于GC的好文章:http://msdn.microsoft.com/en-us/magazine/bb985010.aspxhttp://msdn.microsoft.com/en-us/magazine/bb985011.aspx
此外,Maoni的WebLog有一些很棒的东西(也会给你带来最新的,因为上面的文章都很老了):Link
另外,就在本周,Raymond Chen正在做一个关于GC的系列:Link
这里有一个关于使用Dispose和Finalization的很好的讨论:http://www.bluebytesoftware.com/blog/2005/04/08/DGUpdateDisposeFinalizationAndResourceManagement.aspx