【问题标题】:C# Object ScopeC# 对象范围
【发布时间】:2015-11-05 07:38:28
【问题描述】:

我试图了解对象何时被回收。例如,在一个类中,我有一个 List 声明和这个类中的一个方法,通过声明和初始化一个临时对象然后将该对象添加到列表中来填充列表。

我的困惑:由于临时对象是在方法体中声明的,当方法返回时这些对象不会被回收,因此保存对它们的引用的列表现在失去了对象的值?在方法完成后,我的代码仍然保持对象值(并且可能引用完整)。

public class CameraTest
{

    private List <Camera> cameraList;
    public CameraTest()
    {
        AddCamera();
    }

    private void AddCamera()
    {
        Camera tempCamera = new Camera();
        tempCamera.Name="Camera1";
        cameraList.Add(tempCamera);
    }

   //Why would cameraList still have the "Camera1" object here?

}

【问题讨论】:

  • 如果您包含可以实际编译的代码,您的问题会更好。
  • 首先,您将变量 cameraList 创建为类的全局变量。
  • 只要你有一个 CameraTest 实例并且你找到了一个更好的地方来调用 AddCamera - 即在构造函数中,这些对象仍然存在。
  • 只有在引用计数为0时才会发生垃圾回收
  • 简而言之,只要 somebody 有对它的引用,一个对象就存在并继续存在(从技术上讲,它在被 GC 处理之前仍然存在)。变量 tempCamera 不存在于 AddCamera 方法之外,但是您分配给它然后添加到您的 cameraList 的对象确实存在,因为 cameraList 具有对它的引用。

标签: c# object reference recycle


【解决方案1】:

.NET 中的垃圾收集器是不确定的。一旦不再有对它的引用,一个对象就“准备好收集”,但这并不意味着它会立即被收集。

在您的代码中,cameraList 包含名称为“Camera1”的对象,因为它引用了它,因此无论范围如何,它都会阻止它被收集。

范围适用于变量,而不适用于对象。对象是内存中的引用,而变量只是指向这些引用的指针。你丢失了变量tempCamera,但没有丢失它指向的对象

【讨论】:

  • An object is "ready for collection" once there are no more references to it 这是不正确的。如果是这样,您可能会在 .net 中拥有孤立的岛屿。相反,您可能想写An object is "ready for collection" when it's no longer rooted
  • 所有提供的答案都是有道理的,但是您的变量 vs. 对象语句让重点明白了。
  • @ConradFrix 你当然是对的,但是你必须解释 GC 根对象的概念和关于 GC 工作原理的强化课程,我想这会是一个太长的答案对于这样的问题。我试图让它变得简单:再次,你是对的,如果 OP 想进一步挖掘,我建议this link 但我想“简单但不完全正确”的解释足以开始
【解决方案2】:

简单地说:变量只是一个指向对象的指针(“引用”)。虽然变量可能超出范围,但如果另一个变量或对象(例如您的列表)持有对同一对象的引用,则该对象不会被垃圾回收。

【讨论】:

  • 变量只是一个指针所有变量都是这样吗?
  • @Conrad 不,这就是我说“简单地说”的原因。来自MSDN: Types (C# Reference)“作为值类型的变量存储数据,作为引用类型的变量存储对实际数据的引用。引用类型也称为对象”
【解决方案3】:

因为,虽然 CameraTest 存在,但它引用了 cameraList。虽然cameraList 存在,但它引用已添加到集合中的Camera 的所有实例。

您已将CameraCamera1 实例添加到cameraList。所以有一个引用链会阻止 Camera1 被 GC 收集直到没有人持有对 CameraTest 实例的引用

您应该通过 C# 获取一份 CLR 副本并阅读它。

【讨论】:

    猜你喜欢
    • 2015-09-30
    • 2011-04-29
    • 1970-01-01
    • 1970-01-01
    • 2010-12-11
    • 1970-01-01
    • 2012-04-14
    • 2013-04-11
    • 2014-02-12
    相关资源
    最近更新 更多