C# 引用静态成员垃圾处理的对象

C# 引用静态成员垃圾处理的对象,c#,.net,static,garbage-collection,C#,.net,Static,Garbage Collection,希望你不要介意,我可能错过了什么;我只需要对以下场景进行一些说明:如果对象a包含对静态列表的引用以及该静态列表中的条目,并且对象a不在范围内,它会被垃圾收集吗?我是否需要将对象a对静态列表的引用和对该列表中条目的引用设置为空,然后它才符合条件 我知道静态列表中包含的对象将在应用程序的生命周期内有效,所以我想既然对象a仍然引用该静态列表中的一个条目,那么它仍然在仍然有效的对象的主依赖关系对象图中 提前感谢在您的情况下,静态列表将有效,但将被垃圾收集,因为您无法从任何其他位置访问它,并且没有意义将其

希望你不要介意,我可能错过了什么;我只需要对以下场景进行一些说明:如果对象a包含对静态列表的引用以及该静态列表中的条目,并且对象a不在范围内,它会被垃圾收集吗?我是否需要将对象a对静态列表的引用和对该列表中条目的引用设置为空,然后它才符合条件

我知道静态列表中包含的对象将在应用程序的生命周期内有效,所以我想既然对象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.
}
private static List static_strings=new List()//这不可能
//除非我们
//分配空值或其他值
//列表到静态字符串
公共无效AddOne()
{
字符串a=new Random().Next(0,2000).ToString();//a在范围内,它引用
//指向无法收集的字符串。
静态_strings.Add(a);//现在a和列表都是访问该字符串的方法。
SomeListHolder b=新的SomeListHolder(静态_字符串);//可以收集
//现在,没人在乎
//关于对象所指的内容
//对,只指它所指的东西。
}//a超出范围。
公共无效删除一个()
{
if(static_strings.Count==0)返回;
a=静态_字符串[0];//a在作用域中。
static_strings.RemoveAt(0);//a是访问该字符串的唯一方法。
GC.Collect();//不要在家里尝试。
//a在这里的作用域中,这意味着我们可以在这里编写一些代码
//但是,垃圾收集并不取决于我们所做的
//可以写,这取决于我们写了什么,因为a不是
//使用时间较长,很可能是因为
//编译后的代码不会浪费时间保留引用
//它没有用。
}
如图所示,范围什么都不是,可达性就是一切

对于引用静态对象的对象,它引用的内容是不相关的,只有引用它的内容


特别要注意的是,这意味着循环引用不会阻止项目被收集,这与某些引用计数的垃圾收集方法不同。

谢谢-我明白了-我忽略了您关于它的观点,不管对象引用什么,而是从根对象开始引用什么。因为我的静态列表不是指“a”,所以一旦“a”超出范围,我们都可以使用GC。