Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Which of these objects are eligible for garbage collection?

This is a question I was asked at my interview recently: Which 'Random' object(s) would get collected during the 'GC.Collect()' call?

String a = new Random().Next(0, 1) ==1 ? "Whatever 1" : "Whatever 2";

String b = new WeakReference(new Random()).Target.Next(0, 1) == 1 ?
    "Whatever 1" : "Whatever 2";

GC.Collect();

I answered that this is an implementation-specific question and it highly depends on the GC implementation and the corresponding weak reference semantics. As far as I know, C# specification doesn't provide exact description of what GC.Collect should do and how should the weak references be handled.

However, my interviewer wanted to hear something else.

like image 687
Yippie-Ki-Yay Avatar asked Nov 19 '11 21:11

Yippie-Ki-Yay


4 Answers

Both Random() instances and the WeakReference are eligible for collection:

  • The first Random was not stored in a local, let alone a local that is later read.
  • The second Random was passed to a WeakReference, so would be OK to collect anyway, but the WeakReference itself is not held anywhere, so that too is eligible for collection.

None of the strings are (there are only 2 string instances here, not 4, even if every possible code path was reached): because they are literals in the c# code, they are interned once they exist.

like image 163
Marc Gravell Avatar answered Nov 12 '22 02:11

Marc Gravell


It is true that this is implementation (and compiler) dependant. If all this is in the same method you cannot know which objects are still on the stack. Since objects on the stack are still referenced they wouldn't be collectible.

What the interviewer wanted you most likely to do is to check which objects are still reachable at the call of GC.Collect assuming a "perfect" implementation which discards everything as soon as possible.

like image 27
Zarat Avatar answered Nov 12 '22 04:11

Zarat


However, my interviewer wanted to hear something else.

I expect they wanted to hear an answer like the one Marc Gravell has posted here but that is based upon an over-simplified model of how garbage collected virtual machines work that bears no resemblance to reality.

For example, the call to GC.Collect might get tail call optimized in which case there are no global roots so all heap-allocated blocks get collected. Or the compiler might create a new entry on the stack frame for every temporary (not just variables in the source code) which keeps everything reachable and nothing gets collected. Or the compiler might swap the order of the creation of the strings a and b and collect the Random object referred to by the WeakReference before the Target method is invoked causing a null reference exception so the other Random is never even allocated.

like image 3
J D Avatar answered Nov 12 '22 03:11

J D


GC.Collect is like in Java equivalent to System.gc()

It "recommends" to check for null values to delete them. You can't really depend on this feature since it's really automatic unlike C++.

Hope it helps!

like image 1
Martin Gemme Avatar answered Nov 12 '22 02:11

Martin Gemme