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 objec开发者_StackOverflowt data
references), or is the reference reused in each iteration?
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.
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.
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).
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.
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.
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.
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.
I believe it's a new instance each time. Why would that prevent garbage collection?
精彩评论