(我什至不知道我的问题是否完全有意义;这只是我不理解的问题,并且在我脑海中徘徊了一段时间)
考虑开设以下课程:
public class MyClass
{
private int _myVar;
public void DoSomething()
{
// ...Do something...
_myVar = 1;
System.Console.WriteLine("Inside");
}
}
并使用这样的类:
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");
}
}
(Ideon)
上面,我正在创建一个类的实例,而没有将其分配给变量。
我担心垃圾收集器可能会过早删除我的实例。
我对垃圾回收的幼稚理解是:
“在没有引用指向它的情况下,立即删除它。”
由于我创建实例时未将其分配给变量,因此此条件为true。显然,代码运行正确,所以我的假设似乎是错误的。
有人可以给我我所缺少的信息吗?
总而言之,我的问题是:
(为什么/为什么不这样做)在不将其赋值给变量或return
对其进行实例化的情况下实例化该类是否安全?
即是
new MyClass().DoSomething();
和
var c = new MyClass();
c.DoSomething();
从垃圾收集的角度来看相同吗?
这有点安全。更确切地说,就像您拥有一个在方法调用之后仍未使用的变量一样安全。
当GC可以证明不再有任何对象将不再使用其任何数据时,对象就有资格进行垃圾回收(这与说立即将其进行垃圾回收不同)。
即使实例方法正在执行,如果该方法从当前执行点开始不使用任何字段,则可能会发生这种情况。这可能是非常令人惊讶的,但通常不会有问题,除非您拥有终结器,而终结器在当今已经很少见了。
顺便说一句,当您使用调试器时,垃圾收集器对其收集的内容要保守得多。
这是此“早期集合”的演示-在这种情况下,尽早定型,因为这更容易证明,但我认为它足以清楚地说明这一点:
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
(因为我们需要对象才能检索x
)但在 SomeMethod
完成之前如何最终确定对象。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句