5

In the book C# 5.0 in a Nutshell by Joseph Albahari I found this:

using System; using System.Text; class Test { static void Main() { StringBuilder ref1 = new StringBuilder ("object"); Console.WriteLine (ref1); // The StringBuilder referenced by ref1 is now eligible for GC. StringBuilder ref2 = new StringBuilder ("object2"); StringBuilder ref3 = ref2; // The StringBuilder referenced by ref2 is NOT yet eligible for GC. Console.WriteLine (ref3); // object2 } } 

where it says as soon as you pass the line of code where a variable is last used, the object referenced by it is eligible for garbage collection (that is, if no other variable holds a reference to that object).

However according to this lecture from UC Berkley, as long as a reference to the object exists on the stack, it won't be garbage collected. My understanding is, until the method returns, the variable stays on the stack. Which means any object referenced by it is alive until the method returns.

Is this an error in the book or does Java and .NET garbage collection work differently?

4
  • Read this MSDN article, you'll learn how it works in details. Commented Jul 5, 2013 at 23:09
  • I think the accepted answer misses the point. The "stack" you see in the IL is not the same as the "stack" that the CPU sees. It's only a logical thing used to describe computation; it doesn't actually exist. It's only there as a simplification; the code is optimized before being JIT'ed to assembly. Commented Jul 6, 2013 at 0:59
  • Chapter 3 "Basic concepts", section 3.9 "Automatic memory management" in the official C# language specification answers your question. You can download it from Microsoft. microsoft.com/en-us/download/confirmation.aspx?id=7029. It took me a few minutes to check it out. How long did you compose your question? Commented Jul 6, 2013 at 1:17
  • If you want to ask what freeing of the memory entails, ask precisely that. I don't know about java but C# language specification is clear. It specifies when an object is eligible for collection and it says, that actual collection should occur at some time after the moment of becoming eligible, which means at any time after the moment of becoming eligible. Fraction of a nanosecond after is also after. It doesn't say anything about any stacks. Such implementation details are irrelevant. If java specification does say about stack then it's clearly different. Commented Jul 6, 2013 at 1:36

3 Answers 3

7

However according to this lecture from UC Berkley, as long as a reference to the object exists on the stack, it won't be garbage collected.

You're right. What you're missing is that a reference no longer exists on the stack.

For the code that constructs an object on the stack:

StringBuilder ref1 = new StringBuilder("object1"); 

the variable ref1 is stored on the stack, in some memory location:

 0x403730: Stack Pointer -> 0x40372C: pointer to ref1 0x403728: saved value of EBP 0x403724: saved value of return address 0x403720 

Now comes the next line:

StringBuilder ref2 = new StringBuilder("object2"); 

Where is the pointer to ref2 going to be stored? On the stack: yes. But where on the stack? In the same memory location that was being used for ref1 of course!:

 0x403730: Stack Pointer -> 0x40372C: pointer to ref2 0x403728: saved value of EBP 0x403724: saved value of return address 0x403720 

It would be silly to simply push another value onto the stack:

Stack Pointer -> 0x403730: pointer to ref2 0x40372C: pointer to ref1 0x403728: saved value of EBP 0x403724: saved value of return address 0x403720 

It would be silly because ref1 isn't needed anymore.

That's why ref1 is eligible for garbage collection: there are no longer any references to it.

Sign up to request clarification or add additional context in comments.

3 Comments

I'm not sure why this was downvoted, I didn't read the code carefully enough to see if there was an error. But I feel like this is an overly complicated way of explaining a relatively simple concept (at least, in theory, perhaps not in implementation, but we're not writing a GC here).
what is EBP? You mention "saved value of EBP" in your explanation
The other values are really unimportant; i was just throwing in "possible" values that one might see on a stack. In this case i threw out the jargon base pointer (abbreviated EBP). By convention it points to where the stack was when the function was called (so that the stack pointer (ESP) can be rolled back when the function returns). i could have easily said up, down, strange, or charmed as labels for the other things; i just wanted something sorta real for my made-up stuffs.
7

The book is correct.

In .NET, the garbage collector has information of where in the code the variable is used, and as soon as it's unused, the object is eligible for garbage collection.

(However, if you run the code with a debugger attached, the garbage collector changes behaviour. It keeps the object for the entire scope of the variable, not only where the variable is used, so that the object can be investigated in the debugger.)

Comments

4

My understanding is, until the method returns, the variable stays on the stack. Which means any object referenced by it is alive until the method returns.

The JIT is free to remove the object reference ("variable") any time after it's last usage, so this is not necessarily true.

as long as a reference to the object exists on the stack, it won't be garbage collected

This is true - but the JIT may change when this variable no longer "exists on the stack" in a way that doesn't necessarily match your code.

In C# 5, this can get really confusing, as well, as async methods can get rewritten in ways that variables stick around longer than you'd expect in some scenarios.

That being said, if you need to guarantee that an object is eligible at some point, setting the variable(s) referencing the object to null explicitly allows you to control when it becomes eligible explicitly.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.