希望你不介意,我可能遗漏了一些东西;我只需要对以下情况进行一些说明:如果对象a包含对静态列表的引用以及该静态列表中的条目,并且对象a超出范围,它会被垃圾收集吗?我是否需要将对象a对静态列表的引用和对该列表中条目的引用设置为 null 才能使其符合条件?
我知道静态列表包含将在应用程序的生命周期中存在的对象,所以我在想,因为对象a仍然引用该静态列表中的条目,它仍然在仍然存在的对象的主要依赖对象图中?
提前致谢
希望你不介意,我可能遗漏了一些东西;我只需要对以下情况进行一些说明:如果对象a包含对静态列表的引用以及该静态列表中的条目,并且对象a超出范围,它会被垃圾收集吗?我是否需要将对象a对静态列表的引用和对该列表中条目的引用设置为 null 才能使其符合条件?
我知道静态列表包含将在应用程序的生命周期中存在的对象,所以我在想,因为对象a仍然引用该静态列表中的条目,它仍然在仍然存在的对象的主要依赖对象图中?
提前致谢
在您的情况下,静态列表将存在,但将被垃圾收集,因为您无法从任何其他地方访问它并且将其保存在内存中是没有意义的。您不需要对静态列表的引用为空。
首先,对象不会超出范围,变量会。大多数情况下,区别是语义之一,但在这里很重要。
让我们为您所谈论的内容创建一个具体示例:
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.
}
正如这里所看到的,范围什么都不是,可达性就是一切。
对于引用静态的对象,它所引用的内容无关紧要,只有引用它的内容。
特别要注意,这意味着循环引用不会阻止项目被收集,这与某些引用计数垃圾收集方法不同。