在 C# 中,当我有两个对象obj1、obj2由 a 组成时List<string>
,我将这两个对象都分配给同一个List<string>
对象。
如果我对 obj1 的引用超出了范围,但我对 obj2 的引用没有,那么 obj1 是否仍然有资格进行垃圾回收,或者是否存在一些依赖问题,因为仍然存在对该List<string>
对象的引用?
在 C# 中,当我有两个对象obj1、obj2由 a 组成时List<string>
,我将这两个对象都分配给同一个List<string>
对象。
如果我对 obj1 的引用超出了范围,但我对 obj2 的引用没有,那么 obj1 是否仍然有资格进行垃圾回收,或者是否存在一些依赖问题,因为仍然存在对该List<string>
对象的引用?
只要没有对 obj1 本身的引用,obj1 就应该有资格进行垃圾回收。
如果我对 obj1 的引用超出了范围,但我对 obj2 的引用没有,那么 obj1 是否仍然有资格进行垃圾收集,或者由于仍然存在对 List 对象的引用而存在一些依赖问题?
如果我理解正确,您的意思是两者都属于类型,obj1
并且都指向同一个实例。obj2
List<string>
List<string>
当obj1
超出范围时,仍然会obj2
作为对实例的活动引用List<string>
,因此无法对列表进行垃圾收集。
如果 obj1 是堆上引用类型的一部分(即其属性之一),则它占用的内存空间可能会作为外部对象的一部分被垃圾收集。如果它只是堆栈上的引用,则不会涉及 GC,因为当 obj1 超出范围时,堆栈将在方法调用结束时展开。
请记住,obj1 只是对堆上对象的引用(在某种程度上是指针) - 只有在没有引用指向它时,才会对这个对象进行垃圾收集。
此问题中定义了内存的三种用途:
List<string>
实例的引用obj1
。List<string>
实例的引用obj2
。List<string>
。如果obj1
超出范围,但obj2
没有,则垃圾收集后仅保留以下内容:
List<string>
对名为 的实例的引用obj2
。List<string>
。重要的是要记住,在大多数情况下,C# 抽象出引用的概念,以便您可以安全地认为obj1
andobj2
是List<string>
不是引用,而是引用它们。
引用可能obj1
在本地调用堆栈中,而不是可能在堆上的实例本身。因此obj1
(引用)仅在调用堆栈展开时才被清理。
在您的情况下,obj1
必须有资格进行垃圾收集。
你需要看看这里。它清楚地解释了垃圾收集如何处理对象引用。Jon Skeet's
answer
一个很好的教程给你Object's Lifetime in C#
。
如果obj1
是 List 的成员,则在父 List 被垃圾收集之前,它不能用于垃圾收集。
所以:
List<string> l = new List<string>();
string a = "one";
l.Add(a);
{
string b = "two";
l.Add(b);
}
在此清单的末尾,a
在范围内,b
超出范围,但两者仍然在列表中具有引用l
,因此都没有资格进行垃圾回收。