thumbmunkeys
thumbmunkeys

Reputation: 20764

Local Variables and the Stack

What will happen in the following code snippet:

while (!Done)
{
     Data data = source.GetData();
     sink.ProcessData(data);
}

Is a new reference data put on the stack at each loop iteration (thus preventing garbage collection of the object data references), or is the reference reused in each iteration?

Upvotes: 3

Views: 295

Answers (8)

Eric Lippert
Eric Lippert

Reputation: 660138

Is a new reference data put on the stack at each loop iteration (thus preventing garbage collection of the object data references), or is the reference reused in each iteration?

I think your "main" question about re-use has been adequately answered but the parenthetical is extremely important. Your assumption that this prevents garbage collection is wrong. If the garbage collector detects that the only reference to "data" is the stack slot and that no one is ever going to read from it again then the garbage collector is allowed to reclaim the storage even with the reference on the stack. This could be bad if the thing consuming the stack slot is unmanaged code that the GC doesn't know about.

If you need to keep something alive by holding onto it on the stack then you need to add a KeepAlive to the method.

Upvotes: 8

Xaqron
Xaqron

Reputation: 30857

Nothing happens since compiler would optimize it to something like below at release production :

sink.ProcessData(source.GetData());

If you create variables and dereference them more quickly, heap fragmentation happens, that's the reason we have circular buffers.

Upvotes: 1

Sam B
Sam B

Reputation: 2481

Consider this:

    private class test
    {
        ~test()
        {
        }
    }

    static void Main()
    {
        while (true)
        {
            GC.Collect();
            test t = new test();
        }
    }

t is reused on each loop. But if you set a breakpoint in the Finalizer of the test class, it will be hit after the third time variable t is reassigned.

Upvotes: 1

Tim Barrass
Tim Barrass

Reputation: 4939

I believe it's a new instance each time. Why would that prevent garbage collection?

Upvotes: 0

Jesse C. Slicer
Jesse C. Slicer

Reputation: 20157

The variable is "reused", as you say. Stack/local variables are just that, local to the method and NOT the scope. The scope your data variable is in only keeps it from being seen outside that scope and conversely does NOT define a varying stack slot.

Jon Skeet says it well, as always.

Upvotes: 2

Aliostad
Aliostad

Reputation: 81660

Data if it is a reference type always goes to heap. If it is a ValueType goes to stack here.

The reference itself will be reused.

Upvotes: 1

Adam Houldsworth
Adam Houldsworth

Reputation: 64487

Variables inside the loop do not persist across iterations, so they are effectively flushed each loop - what the compiler does with them under the hood is its business :)

If it is a reference, the pointer is flushed and the object becomes liable for GC assuming you don't hook onto it somewhere else.

Upvotes: 1

perdian
perdian

Reputation: 2843

The reference is put on the stack (the variable itself gets allocated on the heap) and will not be reused each iteration. Instead it becomes unreachable after the while loop has finished and will become eligible for garbage collection (unless you store it somewhere within the sink).

Upvotes: 1

Related Questions