Rumors Re Forcing Garbage Collection (GC) RRS feed

  • Question

  • Hello,

    I've heard a couple of rumors out on the Internet re .Net garbage collection. I'm trying to find an authoritative answer which either confirms or refutes them.


    Rumor 1: Garbage collection can only be requested/suggested but not forced.

    GC.Collect()'s documentation says that it "Forces an immediate garbage collection of all generations." To me, this is clear. Calling GC.Collect() makes the garbage collection run. Is there any reason why a call to GC.Collect() would be interpreted only as a suggestion or request instead of forcing GC to happen?


    Rumor 2: When garbage collection runs, objects eligible for collection may--but are not guaranteed to be--collected.

    • GC.Collect()'s documentation (.Net 4) says "Use this method to try to reclaim all memory that is inaccessible." Does this sentence mean that GC may fail to destroy objects eligible for collection or just that--after destroying unneeded object references--the GC may find it inefficient to rearrange memory to free up all unused space freed by objects it just destroyed (e.g. the reason the GC doesn't rearrange the large object space after destroying large object instances)?
    • If an object is eligible for collection (no references point to it, et al) and I call GC.Collect(), am I guaranteed that it will be destroyed or may the garbage collector decide to skip over it even though it is eligible for collection?


    (Background: I am trying to do testing which relies on the fact that all objects eligible for GC have been destroyed by the garbage collector.)

    Thank you,

    Monday, May 9, 2011 1:02 PM

All replies

  • Both rumors are pointing to the same issue, and are true in some cases.

    We have two type of memory references in .net. Strong and weak. As far as i know a reference is strong unless you declare it as weak. Strong reference simply means that when a memory block is shared among some functions, When the function which has initiated the memory block, goes dead(finished), the memory block will not be collected by GC unless all the functions that are strongly sharing that memory block, finish their job. but WeakReferences are ignored by GC while collecting. This is why GC may not collect all the unused! memory blocks in each attempt.

    When GC's attempt to collect a garbage, fails, it simply increases the generation of that memory reference unless the generation number is maximum(normally 2). The reason that the generation number increases is to increase software performance. You can find detailed information about GC and CLR memory management in MSDN Mag. As far as i can remember, MSDN Magazine had published a series of columns titled CLR Inside out in its 2007 and 2008 monthly releases in which you can find quite a lot of information about GC.

    Note that GC.Collect() has 3 different overloads, and one of them is Collect(Int32, GCCollectionMode). There are 3 GCCollectionModes: Default, Forced and Optimized. But it doesn't have anything to do with what kind of memory blocks should be collected, it's just about the time that collection should be performed. Forced means immediately and Optimized mean ASAP! ;)

    Monday, May 9, 2011 5:29 PM
  • Thanks for this response, @Milad_Soc!

    In the first rumor, I'm referring to whether or not a call to GC.Collect() absolutely forces garbage collection to run, not whether or not a particular object instance is GCed. From the reading of MSDN documentation and MSDN Magazine articles, my understanding is that calling GC.Collect() makes GC happen However, there's a rumor out there that when GC.Collect() is called the GC process may or may not run. Sounds like we both agree that the documentation indicates that forced means forced. I'm hoping that someone from Microsoft can confirm this to help slay this rumor.

    In regards to the second rumor, I'm not trying to figure out how the GC determines if an object is eligible for collection. (I understand that a strongly-referenced object is ineligible for GC and that an object with a finalizable object takes a GC run, then a finalizer run, then another GC run before it is "dead.") Rather, I'm wondering if there are any cases when the a GC.Collect()-initiated GC run chooses not to destroy all objects eligible for collection. To state it differently, when an "all-generation" GC process runs, will GC ever say "yup, I know that object can be collected but I'm not going to do that now".

    To sum the two questions up in one sentence:

    Are there any exceptions when a call to GC.Collect() will result in GC not running OR when a GC.Collect()-induced GC run will not collect all collection-eligible objects?


    Monday, May 9, 2011 9:06 PM
  • Ok, I got it, Now i think i've never even heard about these rumors the way you explaind.

    But, this gets me start to think stuff like this might be possible in .net, coz i'm facing a special situation in a software i'm trying to develop. It seems like .net has some problems in memory management. I've illustrated the problem here:, Though it's not directly related to GC, take a look.

    Tuesday, May 10, 2011 4:55 AM