Gerade bei interaktiven Systemen kann sich Garbage Collection mit den vorgestellten Algorithmen als störende Unterbrechung erweisen. Generationalen Garbage Collection [Lieberman and Hewitt, 1983,Moon, 1984,Ungar, 1984] ist als Antwort auf dieses Problem entwickelt worden. Sie beruht auf der Beobachtung, daß die meisten erzeugten Objekte in typischen Programmläufen nach relativ kurzer Zeit unerreichbar werden (die Altershypothese: ,,most objects die young``). Daher lohnt es, die Garbage Collection vor allem auf junge Objekte zu konzentrieren.
Zu diesem Zweck wird der Heap in mehrere Segmente unterteilt, in denen die Objekte nach Alter4.3 gruppiert werden. Jedes einzelne Segment wird als Generation bezeichnet und enthält Objekte, die grob der gleichen Altersklasse angehören. Neue Objekte werden in der jüngsten Generation angelegt und, nachdem sie ein gewisses Alter erreicht haben, in die nächste Generation ,,befördert``.
Um nun eine Generation Gn unabhängig von den anderen bereinigen zu können, müssen die Referenzen von Objekten aus allen anderen Generationen mit in die Wurzelmenge der zu bereinigenden Generation einbezogen werden. Die Information über Zeiger zwischen Generationen (inter-generational pointers) muß also bei der Garbage Collection mit geringem Aufwand bereitgestellt werden, d.h. sie muß zur Verfügung stehen, ohne die anderen Generationen zu durchsuchen. Um dieser Anforderung zu genügen, müssen die Operationen, die einen Zeiger in ein Objekt schreiben während des Programmablaufes protokolliert werden. Dies geschieht in der Regel durch das Errichten einer ,,Write Barrier`` -- ein Programmstück in der virtuellen Maschine, das bei jeder Schreiboperation ausgeführt wird und dann die entsprechende Protokollierung durchführt.
Um den Aufwand möglichst gering zu halten, wird eine weitere Eigenschaft typischer Programme ausgenutzt: Referenzen verweisen überwiegend von jüngeren auf ältere Objekte. Diese Eigenschaft wird ausgenutzt, indem zusammen mit einer Generation Gn auch alle jüngeren Generationen Gm<n bereinigt werden. Damit benötigt der Garbage Collector lediglich die Pointer von ,,alt`` nach ,,neu``, d.h., daß während des Programmablaufs nur über die selteneren Referenzen von älteren auf jüngere Generationen Buch geführt werden muß. In Abbildung 4.8 sind diese gestrichelt dargestellt.
Ein großer Vorteil dieser Vorgehensweise ist die Tatsache, daß Zeigeroperationen in der jüngsten Generation überhaupt nicht mehr protokolliert werden müssen, da diese ohnehin in jede Garbage Collection mit einbezogen wird. Da die meisten schreibenden Zeigeroperationen auf der jüngsten Generation zu erwarten sind, wird hierdurch ein Großteil der Protokollierung gespart.
Für die Protokollierung der Referenzen von älteren auf jüngere Generationen werden zwei Methoden unterschieden:
Das ,,Remembered Set`` einer Generation muß bei jedem Speichern eines Zeigers in diese Generation in ein Objekt einer älteren Generation angepaßt werden. Dies wird durch eine ,,Write Barrier`` erreicht, deren Aufgabe ist,
Da die Kartengröße eine Potenz von 2 ist kann die Division zum Ermitteln des Indices effizient durch die Schiebe-Operation sra implementiert werden.
Beide geschilderten ,,Write Barriers`` verlagern einen Teil der zu leistenden Arbeit auf die Garbage Collection, um den Code möglichst kurz zu halten. ,,Card Marking`` hat gegenüber ,,Remembered Set`` den Nachteil, daß bei der Garbage Collection immer eine ganze Karte durchsucht werden muß, auch wenn möglicherweise nur ein enthaltenes Objekt einen Zeiger in die jüngere Generation enthält. Weiterhin besteht bei Sprachen ohne Markierung das Problem, den Anfang des ersten Objektes auf einer bestimmten Karte zu finden - beides bedeutet einen weiteren Mehraufwand für die Garbage Collection. Hingegen hängt die Arbeit, die dem Collector durch Pointer-Stores entsteht nicht von der Anzahl der ausgeführten Speicheroperationen, sondern von der Anzahl der markierten Karten ab. Bei wiederholtem Speichern in ein bestimmtes Objekt steigt der Aufwand bei der Verwendung eines ,,Sequential Store Buffers`` also stetig an, während er bei der Verwendung von ,,Card Marking`` konstant bleibt.
Generationale Garbage Collection hat sich zu einem De-Facto-Standard bei der Implementierung virtueller Maschinen entwickelt. So verwenden alle für einen produktiven Einsatz vorgesehenen Maschinen in Anhang A einen generationalen Algorithmus mit 2 Generationen. Dabei werden für die Bereinigung der jeweiligen Generationen unterschiedliche Algorithmen gewählt: Üblicherweise wird für die jüngere Generation ein kopierender Algorithmus verwendet, während für die ältere Generation ein Algorithmus verwendet wird, der Objekte mit einer geringeren Wahrscheinlichkeit bewegt (z.B Abwandelungen von ,,Mark-Sweep``). Die HotSpot VM [Meloan, 1999] verwendet hier einen inkrementellen Algorithmus (siehe Abschnitt 4.4), um auch Pausen für die ältere Generation möglichst kurz zu halten. Weiterhin findet die Allokation vielfach in einem festen Bereich der jüngsten Generation statt, aus dem die Objekte bei ihrer ersten Garbage Collection in den Hauptbereich der jüngsten Generation evakuiert werden. Die Verwendung dieses eden oder nursery genannten Bereichs erhöht die Lokalität bei der Initialisierung von Objekten und ermöglicht effizienteren Code für die Überlaufprüfung, da die Grenze ein konstanter Wert ist.
[Demers et al., 1990] haben eine Implementierung eines generationalen Algorithmus vorgestellt, die Objekte nicht bewegt und sich damit auch zum Erstellen von konservativen und ,,On-The-Fly``-Algorithmen (siehe Abschnitt 4.4) eignet. Dabei entfällt zwar der positive Effekt der Heap-Kompaktierung und der damit verbundenen erhöhten Lokalität und schnellen Allokation, ein generationaler Ansatz verspricht aber, allein aufgrund des verringerten Working-Sets des Collectors, eine Verkürzung der Programmpausen und der insgesamt aufgewendeten Zeit für Garbage Collection.
Generationale Garbage Collection erreicht bei Erfüllung der Altershypothese deutlich verkürzte Unterbrechungen durch Garbage Collection -- [Ungar, 1984] gibt den Faktor 20, [Appel, 1989b] sogar Faktor 50 an. Dabei wird nicht nur die Zeit der meisten Unterbrechungen verringert, sondern auch die Zeit, die insgesamt zur Garbage Collection aufgewendet wird (2% statt 30% bei [Ungar, 1984]). Wird die Hypothese jedoch nicht erfüllt, so können häufige Bereinigungen des gesamten Speichers auftreten. [Ungar and Jackson, 1991] haben beobachtet, daß auch in normalen Programmabläufen übergangsweise Zustände eintreten können, in denen die Altershypothese nicht erfüllt ist. Dies hat zur Folge, daß häufiger alle Generationen im System müssen bereinigt werden, was sogar zu einer Verschlechterung der Performance gegenüber einem nicht-generationalen Algorithmus führen kann.