2012-09-10 139 views
1

我在C#中有一个在[STAThread]上运行的程序。在C#中释放资源

程序定期创建类X的实例并将它们添加到列表中。
经过一段时间后,这些X实例需要执行的任务完成,不再需要该类的实例。
因为我在单线程上运行,并且许多X的这些实例可能同时运行并耗尽资源,即使它们不再需要,我想在释放资源时知道X的实例是完成,以便我的程序不会减慢。

我的代码如下所示:

public partial class Form1 : Form 
{ 
    List<X> myList = new List<X>(); 

    ... 
} 

我想知道:

  1. 执行操作myList.RemoveAt(0)会从内存中删除类X的第一个实例的所有痕迹。
  2. 如果有更好的方法来做到这一点。

谢谢! Chris

+1

我建议你阅读有关处置对象和垃圾收集器。 – Reniuz

回答

2

从列表中删除类不会从内存中删除它的所有跟踪。 C#是一种带有垃圾收集器的托管语言。每当某个特定的对象不再被任何被认为是“活动的”的位置引用时(意味着该引用仍然可以以某种方式在代码中访问),它就可以用于垃圾收集。这仅仅意味着在将来某个不确定的时间,GC可以自由地清除该对象的内存。这可能是马上,也可能是很长一段时间。幸运的是,你几乎从不需要担心这一点;你只需要确保你不再需要它们的时候,不再需要消耗大量内存的对象的引用。

在你的情况下,你没有给出很多细节。在不了解X类的情况下,我认为可能性不会消耗所有那么多的内存,并且你的列表可能不是那么大。鉴于此,只要这不是一个长期运行的任务,需要几天的时间才能完成,如果它比没有被释放的时间长一些,这可能不是一个大问题。

如果这些对象消耗大量内存(如果它们包含大型数据库查询的结果,大型文件的内容等),那么我会问为什么你有第一个列表?您创建了一个类型列表,并声明它在后台线程中使用。整个列表是否传递给后台线程?只是某些项目?如果它被传递给后台线程,那么你很可能不再需要在主线程中引用它(尽管你需要显示更多的代码来确定地说)。

0

不,myList.RemoveAt(0);只从列表中删除对象的引用。但是垃圾收集器(GC)会删除你的完整对象,因为再也没有对它的引用。

如果你不使用非托管内存,只要相信GC,你不知道他什么时候能够精确地移除对象,但没关系,只是让它。

如果你在你的类X使用非托管内存(COM对象,文件句柄等基本上任何有一个Dispose()方法),这是不够的删除对象的引用。在这种情况下,实现IDisposable接口在类X和编写Dispose方法,将调用你在X.使用对象的Dispose梅索德然后更改您的代码

myList[0].Dispose(); 
myList.RemoveAt(0);