views:

395

answers:

3

Hi guys. I'm rereading CLR via C# right now and have some thoughts about garbage collection routine. In book, after zero generation is filled, garbage collection starts and moves all "not garbage" references to the first generation. The same happens when the first generation is filled. But what happens when second generation is filled? There are no other generations to move references. Is CLR simply makes the second generation bigger?

P.s. Thank you for answers and sorry for my English.

+9  A: 

Yes, it will expand the size of Generation 2 if it can. If there is no more space available you will get an OutOfMemoryException.

Andrew Hare
+1  A: 

The different generations of garbage collection are not about having a particular size but about how old the garbage is. None of the generations have size limitations that I know of.

Brian
+1  A: 

From my understanding, there is only one heap (ironically, it's usually depicted as a stack). Objects are promoted to generation 1 not when generation 0 fills, but when they survive a collection. In brief, references are not "moved," the location used to identify where the generation ends is moved.

When the heap gets close to being full, a few things occur:

  1. Each generation is collected, starting from 0 and ending with 2.
    • If collection of generation 0 is sufficient, it will not collect generation 1 and 2.
    • If collection of generation 0 is not sufficient, but collection of generation 1 is, it will not collect generation 2.
  2. The heap is compacted (gaps are removed)
  3. Promote generations
    • Generation 1 survivors are tagged as generation 2.
    • Generation 0 survivors are tagged as generation 1.

Objects that survive collection are then moved to generation 0 (if this is their first collection cycle) or generation 2 (if they have survived more than one collection). This is done for efficiency sake, to ensure that we don't constantly try to collect long-lived objects.

You don't run out of space in generation specific ways. See this article for a good explanation.

Michael Meadows
I don't believe there's any tagging of objects as such. The CLR keeps track of which segments are used by the different generations, so it is the other way around. The CLR can determine the generation of an object by its location on the managed heap.
Brian Rasmussen
@Brian, sorry if I wasn't clear, I meant to say that the runtime keeps track of where each generation ends, so that objects added to the heap "above" those belong to a lower generation. I'm sure I'm oversimplifying, but you're right, there's no "tracking" on a per object basis of what generation it is.
Michael Meadows
Garbage collection runs when zero generation is full, so I think there is no error.
spkenny
@spkenny, since the heap is continguous, garbage collection runs when the heap is full. During the first collection, generation zero is your entire heap, but as objects are moved to higher generations, they still contribute to heap usage, so generation zero's capacity effectively "shrinks."
Michael Meadows