莫非是没有被分配给一个变​​量得到一个类实例垃圾收集太早了? [英] Could a class instance that is not being assigned to a variable get garbage-collected too early?

查看:108
本文介绍了莫非是没有被分配给一个变​​量得到一个类实例垃圾收集太早了?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(我甚至不知道我的问题是否有意义可言;它只是东西,我不理解,并在旋转我的头一段时间)

考虑有下面的类:

public class MyClass
{
    private int _myVar;

    public void DoSomething()
    {
        // ...Do something...

        _myVar = 1;

        System.Console.WriteLine("Inside");
    }
}

和使用这个类是这样的:

And using this class like this:

public class Test
{
    public static void Main()
    {
        // ...Some code...
        System.Console.WriteLine("Before");

        // No assignment to a variable.
        new MyClass().DoSomething();

        // ...Some other code...
        System.Console.WriteLine("After");
    }
}

Ideone

以上,我创建一个类的实例,而不将其分配给一个变​​量。

Above, I'm creating an instance of a class without assigning it to a variable.

我担心,垃圾收集器可能太早删除我的实例。

I fear that the garbage collector could delete my instance too early.

我天真的垃圾收集的理解是:

My naive understanding of garbage collection is:

只要没有引用指向它删除的对象。

"Delete an object as soon as no references point to it."

自从我创建实例,而其分配给一个变​​量,这种情况是真实的。显然,code运行正确的,所以我asumption的似乎的是假的。

Since I create my instance without assigning it to a variable, this condition would be true. Obviously the code runs correct, so my asumption seems to be false.

有人可以给我我缺少的信息?

Can someone give me the information I am missing?

总之,我的问题是:

(为什么/为什么不)是安全的实例化一个类没有它asigning变量或返回荷兰国际集团呢?

(Why/why not) is it safe to instantiate a class without asigning it to a variable or returning it?

即。为

new MyClass().DoSomething();

var c = new MyClass();
c.DoSomething();

这是一个垃圾收集相同点的视图?

the same from a garbage collection point-of-view?

推荐答案

这是的有点的安全。或者更确切地说,它是安全的,因为如果你有其中反正调用方法后未使用的变量。

It's somewhat safe. Or rather, it's as safe as if you had a variable which isn't used after the method call anyway.

这是对象符合垃圾收集(这是不一样的话说,这将是垃圾收集立即)当GC可以证明,没有什么会使用其任何数据了。

An object is eligible for garbage collection (which isn't the same as saying it will be garbage collected immediately) when the GC can prove that nothing is going to use any of its data any more.

这可能发生的即使一个实例方法执行的,如果方法不打算使用的任何字段从当前执行点开始。这可以说是相当惊人的,但通常不是一个问题,除非你有一个终结,这是难以察觉罕见的这些日子。

This can occur even while an instance method is executing if the method isn't going to use any fields from the current execution point onwards. This can be quite surprising, but isn't normally an issue unless you have a finalizer, which is vanishingly rare these days.

当你使用调试器,垃圾收集器的的比较保守的什么它将收集,顺便说一句。

When you're using the debugger, the garbage collector is much more conservative about what it will collect, by the way.

下面是这个早集的演示 - 好,早日定稿在这种情况下,因为这是比较容易证明,但我认为这证明了这一点不够清楚:

Here's a demo of this "early collection" - well, early finalization in this case, as that's easier to demonstrate, but I think it proves the point clearly enough:

using System;
using System.Threading;

class EarlyFinalizationDemo
{
    int x = Environment.TickCount;

    ~EarlyFinalizationDemo()
    {
        Test.Log("Finalizer called");
    }    

    public void SomeMethod()
    {
        Test.Log("Entered SomeMethod");
        GC.Collect();
        GC.WaitForPendingFinalizers();
        Thread.Sleep(1000);
        Test.Log("Collected once");
        Test.Log("Value of x: " + x);
        GC.Collect();
        GC.WaitForPendingFinalizers();
        Thread.Sleep(1000);
        Test.Log("Exiting SomeMethod");
    }

}

class Test
{
    static void Main()
    {
        var demo = new EarlyFinalizationDemo();
        demo.SomeMethod();
        Test.Log("SomeMethod finished");
        Thread.Sleep(1000);
        Test.Log("Main finished");
    }

    public static void Log(string message)
    {
        // Ensure all log entries are spaced out
        lock (typeof(Test))
        {
            Console.WriteLine("{0:HH:mm:ss.FFF}: {1}",
                              DateTime.Now, message);
            Thread.Sleep(50);
        }
    }
}

输出:

10:09:24.457: Entered SomeMethod
10:09:25.511: Collected once
10:09:25.562: Value of x: 73479281
10:09:25.616: Finalizer called
10:09:26.666: Exiting SomeMethod
10:09:26.717: SomeMethod finished
10:09:27.769: Main finished

请注意对象如何完成的的的 X 已印(如我们所需要的对象,以获取<$ C值$ C> X ),但是的的someMethod 完成。

Note how the object is finalized after the value of x has been printed (as we need the object in order to retrieve x) but before SomeMethod completes.

这篇关于莫非是没有被分配给一个变​​量得到一个类实例垃圾收集太早了?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆