C# GC.Collect 如果对象是使用实例构造函数初始值设定项构造的,则不会销毁该对象

标签 c# .net garbage-collection weak-references

<分区>

Possible Duplicate:
Resurrection difference in using Object Initializer

我很难理解垃圾收集器在 C# 中的工作原理(我使用的是 2012,所以是 c# 4.5)。这是我的示例代码:

    public class A
    {
        public int c;
        public A(){}
        public A(int pC)
        {
            c = pC;
        }
    }

    public static void Main()
    {
        // Test 1
        var a = new A {c=199};
        var aRef = new WeakReference(a);
        a = null;
        Console.WriteLine(aRef.IsAlive);
        GC.Collect();
        Console.WriteLine(aRef.IsAlive);
        //            Console.WriteLine(GC.GetGeneration(aRef.Target)); //output 1

        // Test 2
        a = new A (200);
        aRef = new WeakReference(a);
        a = null;
        Console.WriteLine(aRef.IsAlive);
        GC.Collect();
        Console.WriteLine(aRef.IsAlive);
    }

输出为真/真/真/假

在我看来,在这两个测试中,堆上的对象在调用 GC.Collect 之前没有根。但碰巧在测试 1 中,对象通过了强制 gc 运行,而在测试 2 中却没有。那么,使用初始化器有什么神秘的事情发生吗? 我的猜测是,当使用初始化程序时可能会有“一些额外的代码”,这些代码将成为同一对象的强根......

谢谢。

最佳答案

当使用初始化器时说

 var a = new A {c=199}; --------> 1

编译器在堆栈上包含一个额外的引用,使对象通过 GC。
上面的语句(1)结果如下

 var temp = new A() ;
  temp.c=199;
  var a=temp . 

我认为这个临时变量使这个对象在 GC 期间处于事件状态。

请引用这个link

EDIT :正如 TomTom 在评论中提到的那样。如果调试器正在运行,那么 GC 行为将被更改并且变量将保持事件状态直到方法结束,而不是直到最后一次使用。如果我错了请指正

关于C# GC.Collect 如果对象是使用实例构造函数初始值设定项构造的,则不会销毁该对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14493980/

相关文章:

c# - 对象收集位置的 Linq 结果

.net - 使用SVN管理项目代码

java - java中的软引用会不会一下子清空?

java - 带有条件/超时的弱引用

c# - 无法在 wpf 中使用 Type.GetMember 访问私有(private)字段

c# - 在 WPF 中重叠(叠加)图像的更好方法?

.net - 性能:XmlReader 或 LINQ to XML

.net - 在使用 .NET : always, 的响应式扩展时,永远不会或有时会保留对 `IDisposable` 的引用?

c# - 来自 Flex 客户端的 RSA 加密和来自 Web 服务的相应解密

c# - 接口(interface)和类继承。这是一个可以避免的模式吗?