none
Promotion of surviving object to higher generation on Garbage collection RRS feed

  • Question

  • Is it that with every Garbage Collection objects surviving the collections are promoted to higher generation or is it possible that they still remain in the same generation?


    KP
    Thursday, April 9, 2009 11:21 AM

Answers

  • Objects in gen #2 can't go higher.  Surviving #0 and #1 objects move up.  Objects with a finalizer don't move, they wait for the finalizer thread.
    Hans Passant.
    • Marked as answer by Zhi-Xin Ye Wednesday, April 15, 2009 9:30 AM
    Thursday, April 9, 2009 12:57 PM
    Moderator
  • Re Abijah: there is a few documentation on this

    Which type of documentation are you looking for? Searching for "msdn GC" gives couple of promising articles/blogs, e.g.:
        Chris Lyon's 'A Few Good GC Links'
        Maoni's blog about GC
    • Marked as answer by Zhi-Xin Ye Wednesday, April 15, 2009 9:30 AM
    Friday, April 10, 2009 9:12 PM
    Moderator
  • You can also manually pin an object if you want to, and it will be then ignored by GC while garbage collection. Mainly done for making calls to native code.
    Ganesh Ranganathan
    [Please mark the post as answer if you find it helpful]
    • Marked as answer by Zhi-Xin Ye Wednesday, April 15, 2009 9:30 AM
    Monday, April 13, 2009 9:00 AM

All replies

  • Objects in gen #2 can't go higher.  Surviving #0 and #1 objects move up.  Objects with a finalizer don't move, they wait for the finalizer thread.
    Hans Passant.
    • Marked as answer by Zhi-Xin Ye Wednesday, April 15, 2009 9:30 AM
    Thursday, April 9, 2009 12:57 PM
    Moderator
  • Even there are more interesting cases, when you create an object it can be immediately in the 2nd generation.
    For example try

    Byte[] byteArr = new Byte[83 * 1024];
    Byte[] byteArr1 = new Byte[82 * 1024];
    Console.WriteLine(GC.GetGeneration(byteArr));
    Console.WriteLine(GC.GetGeneration(byteArr1));
    GC.Collect();
    GC.WaitForPendingFinalizers();
    Console.WriteLine(GC.GetGeneration(byteArr));
    Console.WriteLine(GC.GetGeneration(byteArr1));
    
    You can see that byteArr is set in 2nd generation.

    Seems Microsoft keeps to heaps, one for all small objects less than 83KB other heap for objects more or equal 83KB.
    Probably this is done for performance issue, for example to avoid the memory defragmentation for big objects, because there will be performance issues while copying big objects.

    If there is anyone from MS, please provide your input, because there is a few documentation on this.
    Friday, April 10, 2009 5:48 PM
  • That's the LOH, Large Object Heap.
    Hans Passant.
    Friday, April 10, 2009 5:58 PM
    Moderator
  • As we can see LOH is never defragmented.
    But as I understand it is the same Heap, with difference that those objects will be removed only when the application extremely needs a memory.
    Friday, April 10, 2009 6:48 PM
  • No, objects from the LOH are removed when there's no reference left to them.  It just never gets compacted.
    Hans Passant.
    Friday, April 10, 2009 7:07 PM
    Moderator
  • Yes of course they are removed, but in very extreme cases. because initially they are in 2nd generation, and GC gets to 2nd generation at last.
    Friday, April 10, 2009 7:39 PM
  • Re Abijah: there is a few documentation on this

    Which type of documentation are you looking for? Searching for "msdn GC" gives couple of promising articles/blogs, e.g.:
        Chris Lyon's 'A Few Good GC Links'
        Maoni's blog about GC
    • Marked as answer by Zhi-Xin Ye Wednesday, April 15, 2009 9:30 AM
    Friday, April 10, 2009 9:12 PM
    Moderator
  • I understand that it does not go higher then #2 what i meant was is it possible that even after collecting #0 generation the objects might still stay in #0 generation without being promoted.
    I have used SOSEX extention to windbg and found that some objects remain in #0 even after collection. I need to check weather these objects have a finalizer, that should make things clearer.
    KP
    Saturday, April 11, 2009 11:18 AM
  • The only explanation for that must be the existence of the Finalizer for that objects.
    Saturday, April 11, 2009 1:39 PM
  • You can also manually pin an object if you want to, and it will be then ignored by GC while garbage collection. Mainly done for making calls to native code.
    Ganesh Ranganathan
    [Please mark the post as answer if you find it helpful]
    • Marked as answer by Zhi-Xin Ye Wednesday, April 15, 2009 9:30 AM
    Monday, April 13, 2009 9:00 AM
  • I found lots of System.Collections.Queue objects in gen #0 even after collections which monitored using perfmon.
    I believe queue doesn't have a finalizer although these objects get promoted in subsequent collections.
    KP
    Wednesday, April 15, 2009 4:44 PM