在内部范围嵌套引用类型对象对垃圾收集没有影响:对还是错? [英] Nesting reference type object in inner scope has no effect on garbage collection: True or False?

查看:168
本文介绍了在内部范围嵌套引用类型对象对垃圾收集没有影响:对还是错?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在阅读从杰弗里里希特的优良书的垃圾收集篇,通过C#CLR。在那里,他通过参照从所述JIT编译器发射的本地代码拆卸列表中所示的如何在GC概念性工作的例子(根标记方式)。从这个例子中,它发生,我认为范围嵌套引用类型似乎对加快嵌套变量的垃圾收集ZERO效果。我不知道如果我理解正确这一点。在任何情况下,可以考虑这2个版本的代码:

I have been reading the Garbage Collection chapter from Jeffrey Richter's fine book, "CLR via C#". There, he illustrated an example of how the GC conceptually works (how roots are marked) by referring to a disassembly listing of native code emitted from the JIT compiler. From that example, it occurred to me that nesting reference types in scope seems to have ZERO effect on expediting the garbage collection of the nested variable. I wonder if I am understanding this correctly. In any case, consider these 2 versions of code:

A)嵌套在内部范围内引用类型变量(Y):

A) Nesting a reference type variable (y) in an inner scope:

namespace scope
{
    class A { public void foo() { } }
    class Program
    {
        static void Main(string[] args)
        {
            A x = new A();
            x.foo();
            {
                A y = new A();
                y.foo();
            }
        }
    }
}

乙)同上,只是X和Y在同一个范围内。

B) Same as above, except that x and y are in the same scope.

namespace scope
{
    class A { public void foo() { } }
    class Program
    {
        static void Main(string[] args)
        {
            A x = new A();
            x.foo();

            A y = new A();
            y.foo();
        }
    }
}



出于好奇,我查生成的IL代码为两个版本,它们都是一样的!

Out of curiosity, I checked the generated IL code for both versions, and they are the SAME!

Q1:所以,这似乎暗示确实,范围界定不以任何方式加快垃圾收集。它是否正确? (注:我知道了使用的语句 - 但我只是好奇就如在2例子说明上述普通的旧作用域的GC的行为)

Q1: So, this seems to imply that indeed, scoping doesn't expedite garbage collection in any way. Is this correct? (Note: I know about the "using" statement - but I'm only curious about the behaviour on the GC of "plain old scoping" as illustrated in the 2 examples above.)

Q2:如果答案为Q1为True,那么我是受了一个对象生存不受范围决心完全不知所措的情况都不可能发生,因为这里描述:
http://www.curly-brace.com/favorite.html

Q2: If the answer to Q1 is "True", then I am utterly perplexed by how a "Object Lifetime is Not Determined by Scope" situation can possibly happen, as described here: http://www.curly-brace.com/favorite.html

推荐答案

垃圾收集部分取决于不管你是在调试器或不运行。我假设我们不是。

Garbage collection partly depends on whether you're running in the debugger or not. I'll assume we're not.

这可能会比你想象的更有侵略性。例如:

It can actually be much more aggressive than you think. For example:

object o = new object();
Console.WriteLine(o);   
Console.WriteLine("hi");
o = new object();



对象可以被垃圾立即二线后收集 - 即长期变量<$ C $前C> 0 退出范围。这也将是真正的没有最后一行

The object can be garbage collected immediately after the second line - i.e. long before the variable o exits scope. This would also be true without the final line.

在换句话说,范围界定不的畅通的垃圾收集 - 因为GC已经更聪明比你想象的。

In other words, scoping doesn't expedite garbage collection - because the GC is already smarter than you might think.

在事实上,垃圾收集器可以的更是的侵略性。考虑下面的代码:

In fact, the garbage collector can be even more aggressive. Consider this code:

Foo f = new Foo();
f.SomeMethod();
Console.WriteLine("Hello");



其中foo是这样的:

where Foo looks like this:

public class Foo
{
    int x = 10;

    public void SomeMethod()
    {
        Console.WriteLine(x);
        for (int i = 0; i < 100; i++)
        {
            Console.WriteLine("Hello");
            Thread.Sleep(100);
        }
    }
}

在理论上,垃圾收集器可以收集的,而的someMethod 运行,只要它走过去的第一个对象线,它实际上是从 X 读。如果有一个终结,你可以有终结的,而的someMethod 一个线程运行在另一个正在运行。可怕的东西。

In theory, the garbage collector can collect the Foo object while SomeMethod is running so long as it's gone past the first line, where it actually reads from x. If Foo had a finalizer, you could have the finalizer running in one thread while SomeMethod was running in another. Scary stuff.

这篇关于在内部范围嵌套引用类型对象对垃圾收集没有影响:对还是错?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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