next up previous contents
Next: Unterbrechung nur an konsistenten Up: Implementierung von Nebenläufigkeit Previous: Blockierende Aufrufe in separaten   Inhalt


Stopping The World

Für die Speicherverwaltung stellt das Thread-System einen wichtigen Dienst zur Verfügung: um einen konsistenten Satz von Wurzelreferenzen innerhalb der Thread-Stacks sicherstellen zu können, müssen alle Threads angehalten werden. Im Falle eines exakten Collectors kommt erschwerend hinzu, daß sich alle Threads an einem konsistenten Punkt mit entsprechenden Referenztabellen befinden müssen.

Da im Allgemeinen nicht an jeder Instruktion eine entsprechende Referenztabelle (2.2.2) zur Verfügung steht, müssen die Threads bis zu einem der nächsten konsistenten Punkte fortfahren. Erst wenn alle Threads an so einem Punkt angehalten haben, kann der Garbage Collector seine Arbeit beginnen. Um die durch eine Garbage Collection verursachten Pausen möglichst klein zu halten, ist es von großer Bedeutung, diese Transition auch für eine große Zahl von Threads effizient vollziehen zu können.

Es lassen sich zwei grundsätzliche Strategien unterscheiden: Polling und Codemodifikation. Polling erfordert, daß Threads regelmäßig an GC points die Aufforderung zur Garbage Collection erfragen und bei positivem Ergebnis die Transition vornehmen. Dies erfordert entsprechenden Code an allen potentiellen Haltepunkten. Zur Platzoptimierung kann man hier z.B. auf ein polling an Aufrufstellen verzichten und dieses statt dessen in Methodenprologen ausführen. Da ein polling an jedem Methodenaufruf und jeder Schleife ausgeführt wird, ist dieser Mechanismus sehr sorgfältig zu optimieren. Die effizienteste Realisierung (Verzweigungen, Unterbrechungen o.ä.) hängt stark von der verwendeten Architektur und dem Betriebssystem ab.

Polling ist im Interpretermodus eine zu vernachlässigende Größe; bei übersetzten Methoden ergibt sich ein anderes Bild. Die Laufzeiteffizienz läßt sich hier durch Codemodifikation signifikant verbessern. Hierzu wird folgendermaßen vorgegangen: um eine Garbage Collection einzuleiten, werden alle Threads suspendiert. Daraufhin wird der Maschinencode der gerade ausgeführten Methoden an designierten Haltepunkten dahingehend modifiziert, daß der Thread eine unbedingte Transition zur Garbage Collection vornimmt. Es ist dabei erforderlich, alle möglichen Kontrollpfade abzudecken. Da ein Methodenaufruf in der Regel mehrere potentielle Ziele hat, ist es sinnvoller, die aufrufende statt die aufgerufenen Methoden zu modifizieren. Die inkonsistenten Threads werden nun wieder aufgeweckt und laufen bis zu einem solchen Punkt - man sagt auch, sie werden vorgerollt. Diese Technik ähnelt dem Vorgehen von Debuggern beim Setzen von Breakpoints. Eine detaillierte Darstellung der Implementierung in der Sun Research VM findet sich in [Agesen, 1998].




next up previous contents
Next: Unterbrechung nur an konsistenten Up: Implementierung von Nebenläufigkeit Previous: Blockierende Aufrufe in separaten   Inhalt

2001-02-28