如果你坚持使用.NET中的托管代码和标准编码(没有任何与CLR不同的东西),有没有理由手动调用GC或请求在未引用的对象上运行终结器?
我问的原因是我有一个在工作记忆集中增长很多的应用程序。我想知道是否打电话
System.GC.Collect();
和
System.GC.RunFinalizers();
会有所帮助,如果它会迫使CLR无法正常做任何事情。
答案 0 :(得分:7)
不,它没有用。不要这样做。 CLR已经以一种很好的方式处理所有与内存管理相关的内容,并且没有显式调用会执行它尚未执行的操作。
尝试在程序中查找内存泄漏:虽然.NET语言是由内存管理的,但并不意味着它总是知道您何时不再使用某个对象。例如,作为事件侦听器附加到其他对象的对象被认为是GC的根,并且不会被收集。
您可以尝试SOS寻找泄密。
如果确实没有泄漏,那么你的程序确实需要它拥有的内存。
答案 1 :(得分:3)
@zneak:实际上,这并非完全正确。我遇到了这样一种情况:在c#中运行大量数据(包括大量创建和销毁托管对象)时,我间歇性地且非确定地耗尽内存。
每个循环手动调用一次垃圾收集修复它。但是,这个是很少见,并且在大多数情况下,将垃圾收集器留给自己是最好的方法,但是,我不会做出一个永远不应该手动的一揽子声明调用GC,因为这是完全错误的。
答案 2 :(得分:2)
是的,它对于编写需要某些Dispose / Finalize方法的确定性调用(例如从测试视图中看到)的单元测试很有用。
答案 3 :(得分:1)
当然有一个原因,否则他们不会提供Collect()方法。尽管如此,他们很少。当知道时,只有永远使用它,并且已经准备好收集一大堆已经升级到第2代的长寿命对象。或者,如果实际被卸载,则释放具有许多您无法跟踪的引用的COM对象。或者解决在不应该调用Dispose()时使用的crummy代码。
很少见。
答案 4 :(得分:1)
另外,System.GC.Collect();当您想要测量某些容器的内存消耗时,这非常有用。例如,您有数据库存储和服务,它缓存索引的数据,这些数据按顺序和同步加载。当您的服务受到内存压力时,它可以卸载大量最近最少使用的数据。
答案 5 :(得分:0)
将其留给CLR。使用一些工具来识别您提到的问题。