C#列表和内存

3

我是C#的初学者,想知道当list1 = null之后,list1是否真的被从内存中移除了。

List<string> list1 = new List<string>()
{
    "carrot",
    "fox",
    "explorer"
};
List<string> list2 = new List<string>();
list2.Add(list1[0]);
list2.Add(list1[1]);
list2.Add(list1[2]);

list1 = null;

这段代码只是用于文档记录,在我的实际情况中,list1对象非常大,我需要将其从内存中删除,并且仅继续使用list2,它是原始list1的一部分。

我假设list1[0]和list2[0]在更新list2[0]之前引用同一个内存对象...这样正确吗?

7个回答

5
有几个问题,让我分别来回答:
1. 当将对list1的引用设置为null时,list1是否从内存中删除? 答:不是。当垃圾收集器在下一次清理堆时清理内存时,列表才会被从内存中删除。这个清理时间由垃圾收集器决定。
2. list1和list2是否引用相同的对象? 答:是的,它们是引用相同的对象。
因此,总之,这意味着您不必处理内存管理。这由垃圾收集器完成。垃圾收集器足够聪明,知道何时收集孤立的对象。所以,不要试图比GC做得更好。在几乎所有情况下,这只会变得更糟。

内存保留是我最大的关注点,因为list1非常大。我猜我需要克隆list2中所需的对象,以确保list1不再被引用并由垃圾收集器正确删除。 - Chris
@Chris:不,你不必克隆对象。只要你的对象是字符串,它们根本无法被克隆。在幕后,它们仍然指向同一个对象。此外,克隆对象不会以任何方式影响垃圾回收器。不要考虑内存。GC知道何时应该清理它。我建议你阅读一些垃圾回收器的HowTos,正如其他答案中已经提到的那样。 - PVitt

2

C#与C/C++不同,没有直接的内存管理。

如果列表对象不再可访问(假设所有使用它的代码都已停止),那么它将无法从对象根访问。这将使GC能够将其标记为可回收对象。

垃圾回收器收集时,内存将被回收。


但是你可以调用 GC.Collect http://msdn.microsoft.com/en-us/library/xe0c2357.aspx。它可能会回收内存。 - Amiram Korach
3
可能会,也可能不会。而且直接调用它是不好的做法。无论如何,那并不是问题所问的。 - Oded
4
是的,但告诉那些刚开始学习C#的人“你可以像这样收集内存”并不是一个好主意。他们缺乏经验会导致严重的滥用。好的建议不仅在于说了什么,还在于留下了什么未说的。 - Jon
同意。在大多数情况下,几乎没有理由调用GC.Collect。实际上,Chris,你甚至不需要关心将列表实例设置为null,因为一旦它超出范围并且不再使用,它将可供垃圾回收,一旦需要释放该内存,它就会被释放。 - stevethethread
感谢您提供的所有答案。我不想调用GC.Collect方法。我的关注点只是为了释放无用的内存。由于代码正在服务器上运行,我希望尽可能地清理它。 - Chris
1
@Chris GC(Garbage Collector)会照顾你的内存。当GC认为需要进行清理时,它会执行清理操作。 - PVitt

2

不能保证列表会被删除。当你将其赋值为空时,它就可以被垃圾回收,并且每当GC被调用时,它都会被回收。

来自MSDN:

一旦对象有资格被销毁,在某个未指定的时间后,对象的析构函数(如果有)将运行。除非通过显式调用覆盖,否则对象的析构函数仅运行一次。

一旦对象的析构函数运行,如果该对象或其任何部分都无法通过执行的任何可能延续访问,包括析构函数的运行,那么该对象被视为不可访问,该对象变得有资格进行回收。

最后,在对象有资格进行回收后的某个时间,垃圾回收器释放与该对象相关联的内存。


2

1

当垃圾回收发生时,其内存将被回收。

有关详细信息,请参见垃圾回收基础知识。 (垃圾回收的条件)


1

将引用设置为null并不会删除内存,但最终它会被垃圾回收。

GC谬论:将对象的引用设置为null会立即强制GC进行回收。

GC真相:将对象的引用设置为null有时会使GC更早地进行回收。

您可以在此处阅读更多信息。


0
在你的代码中,list1和list2指向不同的位置。
只需在list1 = null之前更改list1[1] = "Something different"的值,并在立即窗口中检查list2[1]的值仍将保持为“fox”。

但是,如果您使用

List<string> list2 = list1;

那么list2[1]将会是“Something different”。

注意:在这两种情况下,使list1 = null都不会对list2产生影响,它仍然包含值。


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