Ich suche nach einer guten Speicherbereinigungstechnik für meine Sprache und habe dieses Papier gefunden , in dem Benjamin Goldberg eine Speicherbereinigungstechnik für stark typisierte Sprachen beschreibt, bei der zur Laufzeit keine Typinformationen mehr benötigt werden.
Kurz gesagt, dies erfolgt durch Platzieren eines Zeigers auf eine Garbage Collection-Funktion direkt nach einem Funktionsaufruf direkt im kompilierten Code. Sie erweitern dies dann, um den ML-ähnlichen parametrischen Polymorphismus zu unterstützen.
Nun meine Frage : Wurde daran gearbeitet, wie diese Technik in einer objektorientierten Sprache implementiert werden kann, in der viele Funktionen durch indirekte Aufrufe mithilfe von Zeigern in einer virtuellen Tabelle implementiert werden?
quelle
Antworten:
Wie Häagen-Dazs Eis gibt es auch bei Object Orientation viele Geschmacksrichtungen, allerdings mit mehr Nüssen und Bananen. Daher ist es gefährlich, Ihre Frage sehr allgemein zu beantworten. Bestimmte OO-Sprachen können unerwartete Funktionen aufweisen, die Probleme mit virtuellen Methoden verursachen können. Ich befürchte, dass der Versuch, sich vorzustellen, welche Art von Merkmalen dazu führen könnten, dass etwas schief geht, eine fruchtlose Übung ist. Es ist besser, präzise Fragen zu beantworten.
Das Grundprinzip des tagfreien GC besteht darin, dass Sie jederzeit in der Lage sein sollten, den Speicher ausgehend vom Stapel zu überprüfen und den tatsächlichen Typ aller Blöcke des zugewiesenen Live-Speichers zu kennen (denn genau das benötigt der GC arbeiten). Dies bedeutet auch, an jedem Aufrufpunkt einer Funktion / Methode den aktuellen Status des Aktivierungsblocks des Aufrufers zu kennen, ob auf dem Stapel oder auf dem Heap, dh die aktuellen Variablen des Blocks und ihren Initialisierungsstatus. Die notwendigen Strukturinformationen können als zu interpretierende Datendeskriptoren oder als ausführbare gc-Routinen gespeichert werdenfür eine bessere GC-Effizienz. Der wichtige Punkt der tagfreien GC ist, dass diese Informationen statisch ermittelt werden können, um einmal mit dem Code und nicht mit jeder Instanz eines Typs oder einer Klasse oder einer Funktionsaktivierung gespeichert zu werden. Wenn sich diese Informationen dynamisch ändern können, wie dies bei polymorphen Typen der Fall ist, muss es möglich sein, sie zu berechnen, indem statische Typinformationen über die dynamische Aufrufsequenz verfolgt und zusammengesetzt werden.
Die Tatsache, dass eine Methode virtuell ist und über eine virtuelle Tabelle aufgerufen wird, ist an sich kein Problem. Ein Anrufer muss nicht wissen, was er anruft, da er in Bezug auf GC für seinen eigenen Aktivierungsdatensatz keine Bedeutung hat . Der Angerufene soll sich selbst kennen (der Compiler sorgt dafür) und alle Informationen tragen, die er benötigt. Die Informationen können wie im Fall von Polymorphismus unvollständig sein und müssen aus anderen Typinformationen ergänzt werden, die in der Anrufsequenz verfügbar sind. In einer Sprache wie ML, in der Funktionen als Parameter übergeben oder in Tupel eingegeben werden können, weiß der Aufrufer möglicherweise nicht, welche Funktion er tatsächlich aufruft.
Entscheidend ist, dass der Anrufer in seinem Code weiß, wo er den Angerufenen anruft, um den Status seines Aktivierungsblocks während des Anrufs zu bestimmen. Dies ist statisch vom Anrufpunkt abhängig und kann daher aus der Rücksendeadresse des Angerufenen abgeleitet werden (auf verschiedene Weise, abhängig von den technischen Variationen, die von verschiedenen Autoren verwendet werden). Das entsprechende
gc-routine
kann also auf irgendeine Weise von dieser Absenderadresse gefunden werden. Zum Beispiel kann es direkt nach dem Aufruf im Code sein, aber andere äquivalente Techniken könnten in Betracht gezogen werden. Wenn der Angerufene durch GC unterbrochen wird, ist es möglich, den GC für den Aktivierungsdatensatz des Anrufers durchzuführen. Der Anrufer erledigt keine GC-Arbeit für den Angerufenen, nur für seinen eigenen Aktivierungsdatensatz.Was ein Problem sein kann, ist sicherzustellen, dass der Angerufene den tatsächlichen Typ aller Werte kennt, die an ihn übergeben werden (wie beim Polymorphismus). Genauer gesagt muss es möglich sein, diese Informationen zu finden, wenn der GC auftritt, und muss sich mit dem Aktivierungsdatensatz der tatsächlichen Methode befassen, auf die über eine virtuelle Methode zugegriffen wird.
Ich glaube, dass eine genauere Darstellung dieser letzten Ausgabe von den tatsächlichen Merkmalen und Klassen- / Objektstrukturen der OO-Sprache und ihrer Schreiborganisation abhängt.
Da der Anrufer den Angerufenen nicht kennen muss, sehe ich nicht, dass indirekte Anrufe ein Problem sein können.
Ein weiterer Punkt (Beantwortung des OP-Kommentars) ist, dass es hier nicht darum geht, ob GC aus kompiliertem Code ausgeführt oder aus Deskriptoren interpretiert wird, sondern ob es ein dynamisches Tag für Typinformationen benötigt.
Vorschlag : Um mehr Arbeit dazu zu finden, nehmen Sie Ihre bevorzugten Suchmaschinen (und andere Webressourcen) und suchen Sie nach Artikeln, in denen die Goldberg-Artikel oder ihre Hauptreferenzen zitiert werden. Wenden Sie die Prozedur rekursiv an und fügen Sie gelegentlich Schlüsselwörter wie objektorientiert oder virtuell hinzu .
quelle