我在C#中的[STAThread]
上运行了一个程序。
程序定期创建类X的实例并将它们添加到列表中
经过一段时间后,X的这些实例需要执行的任务完成,不再需要该类的实例。
由于我在单个线程上运行,并且许多X实例可以同时运行并且耗尽资源,即使它们不再需要,我想在我知道X的实例完成时释放资源,这样我的程序不会变慢。
我的代码如下:
public partial class Form1 : Form
{
List<X> myList = new List<X>();
...
}
我想知道是否:
myList.RemoveAt(0)
将从内存中删除第X类第一个实例的所有跟踪。谢谢! 克里斯
答案 0 :(得分:2)
从列表中删除类不会从内存中删除它的所有跟踪。 C#是一种带有垃圾收集器的托管语言。每当某个特定对象不再被任何被认为是“活动”的位置引用时(意味着仍然可以通过某种方式在代码中访问该引用),它就可以*用于垃圾收集。这仅仅意味着在将来某个不确定的时间,GC可以自由地清理该对象的内存。它可能是马上,或者可能是很长一段时间。幸运的是,你几乎不用担心这个;你只需要确保在不再需要它时,你不会持有消耗大量内存的对象的引用。
在您的情况下,您没有提供太多细节。在不知道关于X类的任何事情的情况下,我会说它没有消耗掉那么多内存并且你的列表可能不那么大。考虑到这一点,只要这不是一个长期运行的任务,这将是持续数天,如果它比没有被释放的应该更长一点,它可能不是什么大问题。
如果这些对象消耗了大量内存(如果它们包含大型数据库查询的结果,大文件的内容等),那么我会问你为什么首先要有这个列表?您创建该类型的列表,并声明它正在后台线程中使用。整个列表是否传递给后台线程?只是某些物品?如果它被传递给后台线程,那么你可能根本不需要在主线程中引用它(尽管你需要显示更多的代码来确定)。
答案 1 :(得分:0)
不,myList.RemoveAt(0);
仅从列表中删除对象的引用。但垃圾收集器(GC)将删除您的完整对象,因为它不再引用它。
如果你不使用非托管内存,只要相信GC,你就不知道他什么时候会完全删除这个对象,但是没关系,就这样吧。
如果在类X中使用非托管内存(COM对象,文件句柄等基本上是任何具有Dispose()方法的内存),则删除对象的引用是不够的。在这种情况下,在类X中实现IDisposable接口并编写一个Dispose方法,该方法将调用您在X中使用的对象的Dispose方法。然后将代码更改为
myList[0].Dispose();
myList.RemoveAt(0);