.NET中的垃圾回收最佳实践

3

System.GC.CollectDispose() 有什么区别?

它们的用途不同吗?应该在何时使用它们?最佳实践是什么?


https://dev59.com/RXRB5IYBdhLWcg3w4bKv - Leyu
3个回答

6

最佳实践是尽可能避免调用GC.Collect,并在完成后对所有IDisposable对象调用Dispose


4
或者使用using语句块,它们是安全的异常处理方式。 - Uwe Keim
2
正确,但您没有解决GC和IDisposable并不具有相同的目的这一事实。这两个指南几乎没有关联。 - H H

6
GC.Collect 的目的是告诉垃圾回收器,内存中有一些对象可以被回收,并且现在是合适的时间进行回收。不过,通常情况下你应该让 GC 自己来完成这个工作,因为它本身就是为此而设计的。
如果你认为某些资源不能由 GC 管理,请实现 Dispose 并自己处理这些资源。你需要显式地调用 Dispose 来释放你想要释放的资源。如果你正在实现 IDisposable 接口,那么你也可以通过 Using 语句来完成这个任务。

Ehsan的建议似乎是正确的。 我有一个这样的情况,我们会迭代地通过性能关键部分,然后暂停。 在暂停期间,我们调用GC.Collect,希望避免系统在执行性能关键部分时进行垃圾回收。 这似乎是使用GC.Collect的一个适当案例。 - Dale Barnard

4

System.GC.Collect被调用时,垃圾回收器将回收内存中所有的对象。由托管代码引用的对象不会被视为垃圾进行回收。该方法用于强制系统回收可用内存。

Dispose()不是GC的一部分,但作为最佳实践,您可以使用它。它仅应用于使用未托管资源(如FileStream等)的对象。它应释放其拥有的所有资源。如果您知道某些资源不会被GC释放,则可以使用Dispose()方法。

using语句确保正确使用IDisposable对象。

顺便提一下:GC不会调用Dispose,它会调用终结器(您应该从Dispose(false)调用终结器)

此外,为了确保始终适当地释放资源,Dispose方法应该可以多次调用而不抛出异常。


MSDN说:

“通过调用Collect可以强制进行垃圾回收,但大多数情况下应该避免这样做,因为它可能会导致性能问题。”

请查看此博客

GC.Collect()请求系统立即执行垃圾回收。您不应该这样做;系统通常比您更清楚何时需要进行回收。

因此,最佳实践是:

您可以使用using块或像您提到的那样使用Dispose方法。

为什么应该使用IDisposable和Dispose?

MSDN

在许多情况下,通过实现IDisposable接口,可以避免对象总是需要进行终结的成本。该接口为程序员已知其生存期的资源提供了一种替代方法,并且实际上经常发生这种情况。当然,如果您的对象仅使用内存,则更好;因此根本不需要终结或处置;但是,如果需要终结并且有许多情况下明确管理对象很容易且实际可行,则实现IDisposable接口是避免或至少减少终结成本的好方法。

还可以查看此文章:使用finalize/dispose模式提高垃圾回收器性能


2
几乎永远不要使用析构函数。 - H H
@HenkHolterman:我删除了析构函数部分,因为我认为那是误导性的!这样我的回答更好了吗? - Rahul Tripathi
1
是的,但那不是我的 -1。 - H H
@HenkHolterman:好的...没问题,先生。可能析构函数也误导了其他人! :) - Rahul Tripathi
1
关于您的评论:那已经过时了。当您拥有一个未受管理的资源时,请将其包装在SafeHandle中。不需要析构函数。 - H H

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接