希望你不介意,我可能会遗漏一些东西;我只需要对以下场景做一些澄清:如果对象 a 包含对静态列表的引用以及该静态列表中的条目,并且对象 < em> a 超出范围,是否会被垃圾收集?我是否需要将对象 a 引用设置为静态列表,并在该列表中的条目符合条件之前将其引用为null?
我知道静态列表包含将在应用程序的生命周期中存在的对象,所以我在想,因为对象 a 仍引用该静态列表中的条目,它仍然存在于仍然存在的对象的主依赖对象图中?
提前致谢
答案 0 :(得分:4)
在你的情况下,静态列表将存在,但 a 将被垃圾收集,因为你无法从任何其他地方访问它,并且没有意义将它保存在内存中。您不需要对静态列表进行空引用。
答案 1 :(得分:2)
首先,对象不会超出范围,变量会超出范围。差异是大多数时候的语义之一,但在这里至关重要。
让我们创建一个你所谈论的具体例子:
private static List<string> static_strings = new List<string>();//this won't be
//collected unless we
//assign null or another
//List<string> to static_strings
public void AddOne()
{
string a = new Random().Next(0, 2000).ToString();//a is in scope, it refers
//to a string that won't be collected.
static_strings.Add(a);//now both a and the list are ways to reach that string.
SomeListHolder b = new SomeListHolder(static_strings);//can be collected
//right now. Nobody cares
//about what an object refers
//to, only what refers to it.
}//a is out of scope.
public void RemoveOne()
{
if(static_strings.Count == 0) return;
a = static_strings[0];//a is in scope.
static_strings.RemoveAt(0);//a is the only way to reach that string.
GC.Collect();//Do not try this at home.
//a is in scope here, which means that we can write some code here
//that uses a. However, garbage collection does not depend upon what we
//could write, it depends upon what we did write. Because a is no
//longer used, it is highly possible that it was collected because
//the compiled code isn't going to waste its time holding onto referenes
//it isn't using.
}
如此处所示,范围无关紧要,可达性就是一切。
对于引用静态的对象,它引用的内容是无关紧要的,只有引用它的内容。
请注意,这意味着循环引用不会阻止收集项目,这与某些引用计数的垃圾收集方法不同。