【问题标题】:Stack & Heap & Garbage Collector堆栈 & 堆 & 垃圾收集器
【发布时间】:2013-12-30 14:38:43
【问题描述】:

标题可能有点不正确,但它仍然是关于 Stack & Heap 和 Garbage Collector 的。

我的代码:

    static void Main(string[] args)
    {
        MyInt x = new MyInt();
        x.MyValue = 3;
        MyInt y = new MyInt();
        y = x;
        y.MyValue = 4;
        Console.Read();
    }

    public class MyInt
    {
        public int MyValue;
    }

我的问题:

我是否理解这一点,首先y 是用它指向内存中的新MyInt 的指针创建的,然后y 指针被x 指针替换,现在y 指向同一个对象(它称为对象对吗?)在内存中作为x

并且 y 的对象现在是之前创建的,现在留在堆上,没有任何指向它的指针?它存在于堆上,但没有人指向内存中的这个对象。现在这个对象是垃圾收集器的主题?

我说对了吗?

【问题讨论】:

  • 是的,看起来差不多
  • “不过如此”是一个词:)

标签: c# heap-memory stack-memory garbage


【解决方案1】:

是的,你是对的。好消息是您可以证明使用WeakReference

WeakReference 是一个跟踪另一个引用的对象,但不会阻止它被收集。这使您可以随时检查您的目标引用,并查看它是否已被收集:

private static void Main(string[] args)
{
    MyInt x = new MyInt();
    x.MyValue = 3;
    MyInt y = new MyInt();
    WeakReference reference = new WeakReference(y);
    Console.WriteLine("Y is alive: " + reference.IsAlive);
    y = x;
    y.MyValue = 4;
    Console.WriteLine("Y is still alive: " + reference.IsAlive);
    Console.WriteLine("Running GC... ");
    GC.Collect(2);
    GC.WaitForFullGCComplete();
    Console.WriteLine("Y is alive: " + reference.IsAlive);
    Console.Read();
}

这段代码证明了你的观点,输出如下:

Y is alive: True
Y is still alive: True
Running GC...
Y is alive: False

【讨论】:

    【解决方案2】:

    是的,您的解释是正确的。 首先,变量xy 分别指向不同的值——ab。然后它们指向相同的值a。所以b没有强引用,所以可以选它进行垃圾回收。

    【讨论】: