An object of a reference nesting type in the inner area does not affect garbage collection: True or False?

I read the Garbage Collection from Jeffrey Richter's "CLR via C #". There, he illustrated an example of how the GC works conceptually (as the roots are marked), referring to a demo list of native code emitted by the JIT compiler. From this example, it occurred to me that nested reference types in scope have a ZERO effect to speed up garbage collection of a nested variable. I wonder if I understand this correctly. In any case, consider these 2 versions of code:

A) Insertion of a variable of reference type (y) in the inner area:

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(); } } } } 

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

 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(); } } } 

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

Q1: Therefore, this seems to imply that actually defining a region does not speed up garbage collection. It's right? (Note: I know about the “using” statement, but I'm only curious about the behavior of the “plain old age” on the GC, as shown in the examples above.)

Q2: If the answer to Q1 is "True", then I am completely puzzled by how the situation "Object lifetime is not determined by region" can occur, as described here: http://www.curly-brace.com/favorite.html

+4
scope garbage-collection c #
source share
4 answers

Garbage collection partially depends on whether you work in the debugger or not. I guess we do not.

In fact, it can be much more aggressive than you think. For example:

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

An object can be garbage collected immediately after the second line, that is, long before the variable o goes out of scope. This would also be true without the last line.

In other words, defining an area does not speed up garbage collection - because the GC is already smarter than you think.

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

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

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); } } } 

In theory, a garbage collector can collect a Foo object while SomeMethod running, while it has walked past the first line, where it really reads from x . If Foo has a finalizer, you can run the finalizer in one thread while SomeMethod running in another. Scary stuff.

+8
source share
John, of course, is right. For some additional background, I refer you to the C # spec, which states:

The actual lifetime of a local variable is implementation dependent. For example, the compiler can statically determine that a local variable in a block is used only for a small part of this block. Using this analysis, the compiler can generate code that causes the variable store to have a shorter lifetime than its containing block.

and also important:

The storage referenced by the local reference variable is restored regardless of the lifetime of this local reference variable.

Please note here we distinguish between the lifetime of the link object - that is, when the garbage collector resolves to a step in - and the lifetime of the variable containing the link. As John points out the lifetime as a variable and an object he refers to can be aggressively shortened by the compiler and the garbage collector and, if we can prove that doing this does not release the link, that someone else might be holding onto.

+5
source share

The author of the linked page seems to believe that C # (or should be) is somehow related to C ++. From this position it is not surprising that the “surprising” (in the Principle of Least Sensation) follow. In particular,

A ReadAccessor is an object that provides access to pixel data in an image that is stored in a memory mapped file for performance reasons.

should immediately suggest (at a really fairly basic .NET knowledge level) that ReadAccessor implement IDisposable .

+3
source share

The lifetime of an object does not need volume, it is based on references to this object, and its current generation count in the GC - as soon as it is completely dereferenced, it depends on its generation from time to time.

References to the scope of the method will simply be completely dereferenced at the end of the method (in your example).

Update: or, as John points out, if he is still fully protected, he is intelligent for the GC.

+1
source share

All Articles