3

在 C# 中,当我有两个对象obj1obj2由 a 组成时List<string>,我将这两个对象都分配给同一个List<string>对象。

如果我对 obj1 的引用超出了范围,但我对 obj2 的引用没有,那么 obj1 是否仍然有资格进行垃圾回收,或者是否存在一些依赖问题,因为仍然存在对该List<string>对象的引用?

4

5 回答 5

1

只要没有对 obj1 本身的引用,obj1 就应该有资格进行垃圾回收。

于 2011-07-04T01:42:29.710 回答
1

如果我对 obj1 的引用超出了范围,但我对 obj2 的引用没有,那么 obj1 是否仍然有资格进行垃圾收集,或者由于仍然存在对 List 对象的引用而存在一些依赖问题?

如果我理解正确,您的意思是两者都属于类型,obj1并且都指向同一个实例。obj2List<string> List<string>

obj1超出范围时,仍然会obj2作为对实例的活动引用List<string>,因此无法对列表进行垃圾收集。

如果 obj1 是堆上引用类型的一部分(即其属性之一),则它占用的内存空间可能会作为外部对象的一部分被垃圾收集。如果它只是堆栈上的引用,则不会涉及 GC,因为当 obj1 超出范围时,堆栈将在方法调用结束时展开。

请记住,obj1 只是对堆上对象的引用(在某种程度上是指针) - 只有在没有引用指向它时,才会对这个对象进行垃圾收集。

于 2011-07-04T02:07:04.857 回答
0

此问题中定义了内存的三种用途:

  • 对名为的单个List<string>实例的引用obj1
  • 对名为的单个List<string>实例的引用obj2
  • 的单个实例List<string>

如果obj1超出范围,但obj2没有,则垃圾收集后仅保留以下内容:

  • List<string>对名为 的实例的引用obj2
  • 的实例List<string>

重要的是要记住,在大多数情况下,C# 抽象出引用的概念,以便您可以安全地认为obj1andobj2List<string>不是引用,而是引用它们。

引用可能obj1在本地调用堆栈中,而不是可能在堆上的实例本身。因此obj1(引用)仅在调用堆栈展开时才被清理。

于 2011-07-04T03:24:07.960 回答
0

在您的情况下,obj1 必须有资格进行垃圾收集。

你需要看看这里。它清楚地解释了垃圾收集如何处理对象引用。Jon Skeet's answer

一个很好的教程给你Object's Lifetime in C#

于 2011-07-04T01:43:23.437 回答
-1

如果obj1是 List 的成员,则在父 List 被垃圾收集之前,它不能用于垃圾收集。

所以:

List<string> l = new List<string>();

string a = "one";
l.Add(a);

{
    string b = "two";
    l.Add(b);
}

在此清单的末尾,a在范围内,b超出范围,但两者仍然在列表中具有引用l,因此都没有资格进行垃圾回收。

于 2011-07-04T01:52:31.230 回答