DE69801186T2 - Verfahren und Vorrichtung zum Auffinden von Objekt-Zeigern, für die Erkennung/Sammlung von nicht-referenzierten Daten-Objekten - Google Patents
Verfahren und Vorrichtung zum Auffinden von Objekt-Zeigern, für die Erkennung/Sammlung von nicht-referenzierten Daten-ObjektenInfo
- Publication number
- DE69801186T2 DE69801186T2 DE69801186T DE69801186T DE69801186T2 DE 69801186 T2 DE69801186 T2 DE 69801186T2 DE 69801186 T DE69801186 T DE 69801186T DE 69801186 T DE69801186 T DE 69801186T DE 69801186 T2 DE69801186 T2 DE 69801186T2
- Authority
- DE
- Germany
- Prior art keywords
- pointer
- value
- node
- data structure
- header
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Expired - Fee Related
Links
- 238000000034 method Methods 0.000 title claims description 333
- 238000012545 processing Methods 0.000 claims description 18
- 230000007246 mechanism Effects 0.000 claims description 17
- 238000004590 computer program Methods 0.000 claims description 6
- 238000001514 detection method Methods 0.000 claims description 4
- 230000004044 response Effects 0.000 claims description 3
- 238000005070 sampling Methods 0.000 claims 2
- 230000008569 process Effects 0.000 description 131
- 238000013519 translation Methods 0.000 description 62
- 239000013598 vector Substances 0.000 description 39
- 238000010200 validation analysis Methods 0.000 description 32
- 239000003550 marker Substances 0.000 description 28
- 238000004422 calculation algorithm Methods 0.000 description 24
- 238000005457 optimization Methods 0.000 description 18
- 238000004140 cleaning Methods 0.000 description 15
- 230000008901 benefit Effects 0.000 description 6
- 230000004913 activation Effects 0.000 description 5
- 238000012360 testing method Methods 0.000 description 5
- 238000010276 construction Methods 0.000 description 4
- 230000004048 modification Effects 0.000 description 4
- 238000012986 modification Methods 0.000 description 4
- 230000008859 change Effects 0.000 description 3
- 238000013461 design Methods 0.000 description 3
- 230000006870 function Effects 0.000 description 3
- 230000003068 static effect Effects 0.000 description 3
- 238000013459 approach Methods 0.000 description 2
- 238000010420 art technique Methods 0.000 description 2
- 238000006243 chemical reaction Methods 0.000 description 2
- 238000005538 encapsulation Methods 0.000 description 2
- 230000008520 organization Effects 0.000 description 2
- 238000000926 separation method Methods 0.000 description 2
- 240000005020 Acaciella glauca Species 0.000 description 1
- 230000004888 barrier function Effects 0.000 description 1
- 230000006399 behavior Effects 0.000 description 1
- 238000004364 calculation method Methods 0.000 description 1
- 230000003111 delayed effect Effects 0.000 description 1
- 230000014509 gene expression Effects 0.000 description 1
- 230000003993 interaction Effects 0.000 description 1
- 230000005055 memory storage Effects 0.000 description 1
- 230000003340 mental effect Effects 0.000 description 1
- 235000003499 redwood Nutrition 0.000 description 1
- 238000011160 research Methods 0.000 description 1
- 239000000126 substance Substances 0.000 description 1
- 230000036964 tight binding Effects 0.000 description 1
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F12/00—Accessing, addressing or allocating within memory systems or architectures
- G06F12/02—Addressing or allocation; Relocation
- G06F12/0223—User address space allocation, e.g. contiguous or non contiguous base addressing
- G06F12/023—Free address space management
- G06F12/0253—Garbage collection, i.e. reclamation of unreferenced memory
- G06F12/0269—Incremental or concurrent garbage collection, e.g. in real-time systems
- G06F12/0276—Generational garbage collection
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F16/00—Information retrieval; Database structures therefor; File system structures therefor
- G06F16/20—Information retrieval; Database structures therefor; File system structures therefor of structured data, e.g. relational data
- G06F16/28—Databases characterised by their database models, e.g. relational or object models
- G06F16/289—Object oriented databases
-
- Y—GENERAL TAGGING OF NEW TECHNOLOGICAL DEVELOPMENTS; GENERAL TAGGING OF CROSS-SECTIONAL TECHNOLOGIES SPANNING OVER SEVERAL SECTIONS OF THE IPC; TECHNICAL SUBJECTS COVERED BY FORMER USPC CROSS-REFERENCE ART COLLECTIONS [XRACs] AND DIGESTS
- Y10—TECHNICAL SUBJECTS COVERED BY FORMER USPC
- Y10S—TECHNICAL SUBJECTS COVERED BY FORMER USPC CROSS-REFERENCE ART COLLECTIONS [XRACs] AND DIGESTS
- Y10S707/00—Data processing: database and file management or data structures
- Y10S707/99951—File or database maintenance
- Y10S707/99956—File allocation
- Y10S707/99957—Garbage collection
Landscapes
- Engineering & Computer Science (AREA)
- Theoretical Computer Science (AREA)
- Databases & Information Systems (AREA)
- Physics & Mathematics (AREA)
- General Engineering & Computer Science (AREA)
- General Physics & Mathematics (AREA)
- Data Mining & Analysis (AREA)
- Memory System (AREA)
- Information Retrieval, Db Structures And Fs Structures Therefor (AREA)
- Stored Programmes (AREA)
Description
- Diese Erfindung bezieht sich auf das Gebiet der Computerspeicherzuordnung und -zuordnungsaufhebung. Genauer ist diese Erfindung ein neues und nützliches Verfahren, eine neue und nützliche Vorrichtung, ein neues und nützliches System, ein neues und nützliches Computerprogrammprodukt und ein neuer und nützlicher Speicher mit einer Datenstruktur zum automatischen Wiedergewinnen einer Speicherablage, wenn die Ablage von einem ausgeführten Computerprogramm nicht mehr verwendet wird.
- Speicherzuordnungs- und -zuordnungsaufhebungstechniken sind in der strukturierten Programmierung und in objektorientierten Programmiermethodiken sehr wichtig geworden. Der von einer Halde zugeordnete Speicher kann zum Speichern von Informationen verwendet werden. Häufig sind diese Informationen ein instanziiertes Objekt in einem objektorientierten Paradigma. Die nachfolgend beschriebenen Techniken betreffen sowohl Knoten in der Halde, die Daten enthalten, als auch Knoten in der Halde, die instanziierte Objekte sind.
- Der Computerspeicher ist ein Betriebsmittel. Programme bewirken, daß ein Computer basierend auf im Speicher gespeicherten Befehlen Operationen ausführt (ablaufen läßt). Das Ausführen von Programmen nutzt ebenfalls Speicher zum Speichern von Informationen. Diese Informationen sind häufig in speicherresidenten Datenstrukturen organisiert. Üblicherweise sind diese Datenstrukturen durch Zeiger von einer Struktur auf eine andere, auf die über Zeiger in der statischen Ablage und in der Stapelvariablenablage Bezug genommen wird, miteinander verknüpft. Das Management des Speicherbetriebsmittels erfolgt in der Weise, daß die Speicheranforderungen für Informationen und Programmcode erfüllt werden.
- Beim Ausführen von Programmen wird häufig Speicher für einen Zweck benötigt, der sich über einen beschränkten Zeitraum erstreckt. Beispielsweise kann ein Programm Speicher zum Halten von Informationen zuordnen, die Informationen in dem zugeordneten Speicher speichern und die gespeicherten Informationen zum Erzeugen eines Ergebnisses bearbeiten, woraufhin kein weiterer Bedarf an den gespeicherten Informationen besteht. Wenn das Programm die gespeicherten Informationen nicht mehr benötigt, kann der zugeordnete Speicher zur späteren erneuten Verwendung freigegeben werden.
- Moderne Programmiersprachen stellen Einrichtungen für die statische Zuordnung, für die Stapelzuordnung und für die Haldenzuordnung von Speicher bereit. Die statische Zuordnung bindet Variablen zur Kompilier- und/oder Bindezeit an Speicherplätze. Die Stapelzuordnung schiebt einen Aktivierungsrahmen auf den Computerstapel, wenn ein Programmblock auf die Durchführung vorbereitet wird. Dieser Aktivierungsrahmen enthält eine Ablage für Variablen im Umfang der Ausführung für den Programmblock. Wenn der Programmblock abgeschlossen wird, wird der Aktivierungsrahmen vom Stapel abgehoben. Somit speichern die Stapel Informationen auf Zuletzt-Eingeben/Zuerst-Ausgeben-Art (LIFO-Art). Die in dem Aktivierungsrahmen gespeicherten Variablen werden von einer Aktivierung des Blocks bis zur nächsten nicht gesichert. Die Haldenzuordnung ermöglicht, daß Speicher für Variablen in irgendeiner Reihenfolge zugeordnet und die Zuordnung in irgendeiner Reihenfolge aufgehoben wird, wobei diese Variablen die Prozedur (oder den Block), die sie erzeugt hat, überleben können. Wenn die Zuordnung des Speichers aufgehoben wird, ist er zur erneuten Zuordnung für eine andere Verwendung verfügbar.
- Ein "Knoten" ist von einer Halde zugeordneter Speicher. Auf Knoten wird über Zeiger zugegriffen. Ein direkter oder (einfacher) Zeiger ist die Knotenadresse in der Halde. Ein (gelegentlich 'Zugriffsnummer' genannter) indirekter Zeiger zeigt auf eine Adresse im Speicher, die die Adresse des Knotens enthält. Es existieren komplexere Zeiger. Indirekte Zeiger ermöglichen, die Knoten in die Halde zu verschieben, ohne daß die Vorkommen der Zugriffsnummer aktualisiert werden müssen. Ein Problem bei indirekten Zeigern besteht darin, daß sie zum Ereichen des Knotens einen zusätzlichen Speicherzugriff benötigen. Dieser zusätzliche Speicherzugriff verlangsamt die Ausführung des Programms.
- Die "Wurzelmenge" ist eine Menge von Knotenbezugnahmen, so daß die Knoten, auf die Bezug genommen wird, unabhängig vom Zustand der Halde aufrechterhalten werden müssen. Ein Knoten ist erreichbar, wenn der Knoten in der Wurzelmenge liegt oder wenn auf ihn von einem erreichbaren Knoten Bezug genommen wird. Die "Bezugnahmemenge" ist die Menge der in einem Knoten enthaltenen Knotenbezugnahmen. Wenn ein Knoten von der Wurzelmenge aus unerreichbar wird und nie wiedergewonnen wird, tritt ein Speicherleck auf. Ein Speicherleck verringert die Menge des für das Programm verfügbaren Haldenspeichers. Ein Knoten, der von der Wurzelmenge aus unerreichbar wird und wiedergewonnen werden kann, ist ein Datenabfallknoten.
- Die Verwendung des Haldenspeichers kann durch manuelles Programmieren der Knotenzuordnung und -zuordnungsaüfhebung ausgeführt werden. Obgleich ein Programmierer weiß, wann ein neuer Knoten benötigt wird, ist es für den Programmierer aber häufig schwierig zu wissen, wann ein Knoten nicht mehr erreichbar ist. Somit können Probleme auftreten, wenn Programmierer die Zuweisung von Knoten explizit aufheben. Eines dieser Probleme besteht darin, daß es sehr schwierig ist, Speicherlecks auszutesten. Häufig verdeckt der Entwurf der Anwendung, die gerade programmiert wird, wann der Programmierer die Zuordnung von Speicher explizit aufheben kann. Wenn ein Teil eines Programms zum Aufheben der Zuordnung von Speicher bereit ist, muß außerdem sicher sein, daß kein anderer Teil des Programms diesen Speicher verwenden wird. Somit müssen in objektorientierten Programmiersprachen (OOP-Sprachen) mehrere Module beim Speichermanagementprozeß eng zusammenarbeiten. Im Gegensatz zur OOP- Programmiermethodik führt dies zur engen Bindung zwischen angeblich unabhängigen Modulen.
- Diese Schwierigkeiten werden minimiert, wenn der Programmierer die Zuordnung von Speicher nicht explizit aufzuheben braucht. Automatische Speicherbereinigungsverfahren tasten den Speicher nach Knoten, auf die Bezug genommen wird, ab und gewinnen Datenabfallknoten zurück - was allerdings einen Aufwand erfordert. Der Prozeß des Findens und Aufhebens der Zuordnung von Datenabfallknoten dauert Prozessorzeit. Da die Hauptfunktion des Programms eine zeitaufwendige Operation oder eine ununterbrochene Anwenderwechselwirkung erfordern kann, ist es wichtig, die Auswirkung des Speicherbereinigungsprozesses auf ein ausgeführtes Programm auszugleichen. Echtzeitsysteme (jene Systeme, die innerhalb einer spezifizierten Taktzeit eine Antwort liefern müssen) können der Speicherbereinigung häufig keine großen Mengen an Prozessorzeit widmen. In Echtzeitsystemen muß der Speicherbereinigungsalgorithmus unterbrochen werden können.
- In einem System, das die Speicherbereinigung verwendet, werden Knoten, wenn Speicher benötigt wird, von der Halde zugeordnet. Diese Knoten werden anfangs nicht wiedergewonnen, wenn sie nicht Mehr benötigt werden. Statt dessen wird der Speicherbereinigungsprozeß, wenn ein Speicherzuordnungsversuch fehlschlägt oder als Antwort auf irgendeine Bedingung (beispielsweise das Ablaufen eines Taktgebers), automatisch aufgerufen, wobei ungenutzter Speicher zur nachfolgenden erneuten Verwendung wiedergewonnen wird.
- Einige Speicherbereinigungsverfahren kopieren Knoten (d. h. diese Verfahren ordnen Knoten, die zu leben scheinen, von einem Platz in der Halde einem anderen Platz neu zu). Wenn dies geschieht, wird ein Mechanismus benötigt, der ermöglicht, daß existierende Zeiger auf den ursprünglichen Platz des Knoten zum Zugriff auf den verschobenen Knoten verwendet werden. Diese Mechanismen umfassen (unter anderem) das Aktualisieren existierender Zeiger auf den ursprünglichen Platz des Knotens und das Liefern indirekter Zeiger auf den neuen Platz des Knotens.
- Der Stand der Technik in der Speicherbereinigung ist gut diskutiert in Garbage Collection, Algorithms for Automatic Dynamic Memory Management, von Richard Jones und Rafael Lins, John Wiley & Sons, ISBN 0-471-94148-4, Copyright 1996, das den Stand der Technik angibt. Weitere Beschreibungen des Standes der Technik sind zu finden in 'Compiler support for garbage collection in a statically typed language', ACM Sigplan Notes, Bd. 27, Nr. 7, 1. Juli 1992, und EP-A-0439920 von Hewlett Packard.
- Speicherbereinigungsalgorithmen können als 'exakt' oder 'konservativ' klassifiziert werden. Diese exakten Algorithmen arbeiten dadurch, daß sie Variablen verfolgen, von denen bekannt ist, daß sie Zeiger enthalten. Diese Algorithmen werden häufig durch Compiler-Abwandlungen unterstützt, die zwischen Zeigern und Datenwerten unterscheiden helfen. Datenwerte und Zeiger werden häufig gekennzeichnet, um zwischen ihnen zu unterscheiden. Die konservativen Algorithmen erhalten weder irgendwelche Hilfe von dem Compiler noch werden die Datenwerte gekennzeichnet. Somit können die Speicherbereinigungsalgorithmen nicht zwischen Datenwerten und Zeigerwerten unterscheiden, so daß alles, das wie ein Zeiger aussieht, als Zeiger behandelt wird. Ferner kennen die konservativen Algorithmen nicht die Struktur der Halde oder des Stapels und erwarten nicht, daß Zeiger gekennzeichnet sind. Die konservativen Algorithmen an sich müssen Schritte zum Behandeln fehlidentifizierter Zeiger enthalten. Viele Speicherbereinigungsalgorithmen sind eine Mischung exakter und konservativer Techniken.
- Generations-Speicherbereinigungstechniken nutzen die Beobachtung, daß viele von der Halde zugeordnete Knoten nur während einer kurzen Zeitdauer genutzt werden. Diese Knoten werden für einen spezifischen kurzzeitigen Zweck zugeordnet und für den Zweck genutzt, woraufhin die Zuordnung für eine mögliche spätere Wiederverwendung aufgehoben werden kann. Da während des Speicherbereinigungsprozesses weniger Knoten untersucht zu werden brauchen, sind somit Speicherbereinigungsalgorithmen, die sich auf jüngere Knoten konzentrieren, effizienter als jene, die sämtliche Knoten völlig gleich verarbeiten.
- Generations-Speicherbereinigungsalgorithmen trennen die Knoten je nach Alter des Knotens in zwei oder mehr Bereiche in der Halde. Jeder Bereich ist eine Generation. Die Knoten werden zuerst von dem Erzeugungsbereich in der jüngsten Generation zugeordnet, während sie in die ältere Generation kopiert werden, wenn der Knoten lange genug überlebt ("lange genug" ist häufig bis zur nächsten Reinigungsoperation). Diese Speicherbereinigungsalgorithmen konzentrieren sich auf das Wiedergewinnen von Ablage von dem Bereich der jüngsten Generation, wo der meiste Datenabfall gefunden wird. Allgemein ist die Anzahl lebender Knoten in der jüngsten Generation wesentlich kleiner als die Anzahl lebender Knoten in den Bereichen anderer Generationen, so daß die zum Reinigen von Knoten im Bereich der jüngsten Generation benötigte Zeitdauer kleiner als die zum Reinigen der Bereiche anderer Generationen benötigte Zeitdauer ist. Irgendeine Reinigungsoperation des Erzeugungsbereichs wird Nebensammlung genannt. Irgendeine Speicherbereinigungsoperation an einem Bereich für eine ältere Generation wird Hauptsammlung genannt. Wegen des verringerten Organisationsaufwands und der höheren Effizienz des Nebensammelprozesses findet die Nebensammeloperation häufiger als die Hauptsammeloperation statt.
- Allerdings müssen Generations-Speicherbereinigungsalgorithmen generationsübergreifende Zeiger aufzeichnen. Diese generationsübergreifenden Zeiger werden erzeugt (1) durch Speichern eines Zeigers in einem Knoten oder (2) wenn ein Knoten, der einen Zeiger enthält, in einen Bereich für eine ältere Generation kopiert wird. Die von einem Kopieralgorithmus erzeugten Zeiger können von dem Kopieralgorithmus erkannt werden. Zum Auf zeichnen von Zeigern, die durch eine Zuweisung eines Zeigers in einem Knoten erzeugt werden, wird eine Schreibsperre verwendet. Wenn jedesmal, wenn ein Bereich für eine ältere Generation gesammelt wird, sämtliche Bereiche für die jüngeren Generationen gesammelt werden, braucht die Schreibsperre lediglich Zeiger von dem Bereich für die ältere Generation auf den Bereich für die jüngere Generation aufzuzeichnen.
- Obgleich eine Nebensammeloperation schneller als eine Hauptsammeloperation ist, erfordert die Nebensammeloperation häufig zuviel Zeit, um in einer Echtzeitsituation befriedigend zu sein. Somit muß der Nebensammelprozeß unterbrochen werden, um den Echtzeitanforderungen zu genügen. Eine Schwierigkeit beim Unterbrechen der Nebensammlung besteht darin, daß die knotenübergreifenden Zeiger in einem unbestimmten Zustand verbleiben, so daß einige knotenübergreifende Zeiger auf den weitergebrachten Knoten zeigen, während andere auf den ursprünglichen Knoten zeigen. Das heißt, wenn die Nebensammeloperation nach dem Kopieren eines Knotens unterbrochen wird, werden häufig nicht alle Bezugnahmen auf den früheren Platz des Knotens auf den neuen Platz des Knotens aktualisiert.
- Wenn ein Knoten kopiert worden ist, müssen irgendwelche Zeiger auf den kopierten Knoten aktualisiert oder verfolgt werden, so daß zukünftige Bezugnahmen auf den kopierten Knoten schließlich erfolgreich sind. Ferner muß auf Zeiger auf Knoten in der jüngeren Generation, die in kopierten Knoten enthalten sind, zugegriffen werden, um die Bezugsmenge zu bestimmen.
- Fig. 1a zeigt einen mit dem allgemeinen Bezugszeichen 100 bezeichneten Haldenbereich. Der Haldenbereich 100 enthält einen Generations-Speicherbereinigungsbereich 101. Der Generations-Speicherbereinigungsbereich 101 enthält eine jüngere Generation 103 und einen Bereich 105 für die ältere Generation. Der jüngere Bereich 103 ist häufig in einen Erzeugungsbereich 107, einen 'Zu'-Bereich 109 und einen 'Von'-Bereich 111 unterteilt. Die Knoten (wie etwa ein neuer Knoten 113) werden zuerst in dem Erzeugungsbereich 107 erzeugt. Wenn sich der Erzeugungsbereich 107 füllt, vertauschen sich die Bedeutungen des 'Zu'-Bereichs 109 und des 'Von'-Bereichs 111. Daraufhin werden aktive Knoten wie etwa der neue Knoten 113 zusammen mit aktiven Knoten indem 'Von'-Bereich 111 in den 'Zu'-Bereich 109 kopiert. Wenn sich der 'Zu'-Bereich 109 füllt, werden aktive Knoten in dem 'Zu'-Bereich 109 in den Bereich 105 für die ältere Generation kopiert. Dies führt zu einem weitergebrachten Knoten 115 in dem Bereich 105 für die ältere Generation. Der Fachmann auf dem Gebiet versteht, daß andere Generations-Realisierungen existieren. Ferner versteht der Fachmann auf dem Gebiet, daß der Erzeugungsbereich 107 die jüngsten Knoten enthält.
- Der Prozeß zum Bestimmen der Wurzelmenge dauert häufig erhebliche Prozessorzeit zum Suchen nach Zeigern in der Halde. Eine im Stand der Technik verwendete Optimierung besteht im Teilen der Halde in (Karten genannte) gleichgroße Gebiete und im Markieren jeder Karte, wenn in der Karte eine Schreiboperation stattfindet - eine Form einer Schreibsperre. Somit werden beim Aktualisieren der Wurzelmenge (anstelle sämtlicher Karten in dem Haldenspeicher) nur die als 'unrein' markierten Karten nach Zeigern durchsucht. Fig. 1b zeigt die Verwendung der Kartenmarkierung. Ein allgemeines Bezugszeichen 120 veranschaulicht ein kartenmarkiertes Gebiet des Speichers 121. Das kartenmarkierte Gebiet des Speichers 121 enthält eine erste Karte 123 und eine zweite Karte 125. In dieser Darstellung ist die erste Karte 123 im Speicher benachbart zur zweiten Karte 125. Somit sind über die erste Karte 123 und über die zweite Karte 125 mehrere Knoten (A-F) 127 verteilt. Der ersten Karte 123 ist eine erste Kartenmarkierung 129 zugeordnet, während der zweiten Karte 125 eine zweite Kartenmarkierung 131 zugeordnet ist. Wenn der Speicher in einer der Karten 123, 125 modifiziert wird, wird der entsprechende Kartenmerker gesetzt. Somit wurde in der Darstellung aus Fig. 1b in der ersten Karte 123 eine Schreiboperation ausgeführt, was dazu führte, daß der Merker 129 der ersten Karte als 'unrein' markiert wird, was durch das 'X' in dem Merker 129 für die erste Karte angegeben wird. Die Tatsache, daß der Merker 131 für die zweite Karte nicht markiert ist, gibt an, daß seit der letzten Reinigung kein Speicher in der zweiten Karte 125 modifiziert worden ist. Die Tatsache, daß ein Knoten 'D' 133 über die Grenze zwischen der ersten Karte. 123 und der zweiten Karte 125 verläuft, verkompliziert die Fähigkeit zum Erfassen des Anfangs des Knotens. Da die Speicherlöschoperation des Computers häufig schneller als eine Wertspeicheroperation ist, werden die Kartenmarkierungen allgemein sämtlich auf Einsen (FF hex) initialisiert.
- Häufig ist es bei Verwendung der Kartenmarkierung erforderlich, ausgehend von einem Zeiger auf eine Adresse im Inneren des Knotens oder auf einen Index in eine Karte den Anfang eines Knotens zu finden. Im Stand der Technik erfolgt dies typischerweise durch Rückwärtsabtasten im Speicher, wobei von dem Anfangszeiger (oder vom Anfang einer Karte) aus nach dem Knoten-Header gesucht wird. Bei Programmiersprachenrealisierungen, die ganze Zahlen, Objekt-Header und Zeiger nicht differenzieren oder kennzeichnen, funktioniert aber das Rückwärtsabtasten wegen der Unfähigkeit, den Anfang des Codes zu erfassen, nicht.
- Ein weiteres Ziel der Kartenmarkierung bei Verwendung mit einem Generations-Speicherbereinigungsalgorithmus besteht im Überspringen von Objekten in dem Bereich der kopierten Generation der Halde, die nicht Bezug auf Objekte in dem Erzeugungsbereich der Halde nehmen. Dieses Ziel wird aber verfehlt, wenn die Dichte dieser Knoten in der älteren Generation so beschaffen ist, daß die meisten Karten markiert sind. Fig. 1c zeigt dieses Problem des Standes der Technik mit einer mit dem allgemeinen Bezugszeichen 140 bezeichneten 'Kartenmarkierungsstruktur'. Ein 'jüngerer Bereich der Halde' 141 enthält wenigstens einen Knoten 143, 145, 147. Ein 'Bereich für die ältere Generation der Halde' 149 ist in mehrere Karten 151, 153 geteilt. Der Karte 151 ist eine 'Kartenmarkierung' 155 zugeordnet, während der Karte 153 eine 'Kartenmarkierung' 157 zugeordnet ist. Eine 'Kartengrenze' 159 gibt das Ende der Karte 151 und den Anfang der Karte 153 an. Der ' Bereich für die ältere Generation der Halde' 149 enthält eine 'Anzahl von Knoten (A-F)' 161 mit einem 'Knoten E' 163 und einem 'Knoten C' 165. Der 'Knoten E' 163 enthält einen Zeiger auf den Knoten 145, und der 'Knoten C' 165 enthält einen Zeiger auf den Knoten 143, wobei beide in dem 'jüngeren Bereich der Halde' 141 liegen. Da ein Knoten in der Karte 151 auf den 'jüngeren Bereich der Halde" 141 Bezug nimmt, ist die 'Kartenmarkierung' 155 markiert. Da ein Knoten in der Karte 153 auf den 'jüngeren Bereich der Halde' 141 Bezug nimmt, ist die 'Kartenmarkierung' 157 markiert. Somit muß selbst unter Verwendung der Kartenmarkierung jeder Knoten in dem 'Bereich für die ältere Generation der Halde' 149 auf Zeiger auf den 'jüngeren Bereich der Halde' 141 geprüft werden. Dies beseitigt den durch die Verwendung der Kartenmarkierung gesuchten Vorteil.
- Ein weiteres Problem bei der Kartenmarkierung besteht darin, daß die Operation des Abtastens der Kartenanzeigen zum Finden der markierten Karten, da zum Lokalisieren eine große Anzahl von Speicherplätzen (jene, die den Markierungsvektor enthalten) der markierten Karten untersucht werden muß, eine Organisationsaufwandoperation ist.
- Eine Kartenmarkierungsrealisierung ist beschrieben in A Fast Write Barrier for Generational Garbage Collectors von Urs Hölzle, vorgestellt auf dem OOPSLA '93 Garbage Collection Workshop in Washington D. C. im Oktober 1993. Diese Abhandlung erläutert den Stand der Technik und ist im Internet zu finden unter:
- "http://self.sunlabs.com/papers/write-barrier.html".
- Die objektorientierte Programmierung (OOP) ist eine Methodik zum Bauen von Computer-Software. Die Schlüssel- OOP-Konzepte umfassen die Datenkapselung, die Vererbung und den Polymorphismus. Obgleich diese drei Schlüsselkonzepte den OOP-Sprachen gemeinsam sind, realisieren die meisten OOP-Sprachen die drei Schlüsselkonzepte unterschiedlich. Objekte enthalten Daten und Methoden. Die Methoden sind Prozeduren, die allgemein auf die Objektdaten zugreifen. Der Programmierer, der das Objekt verwendet, braucht sich nicht um den Typ der Daten in dem Objekt zu kümmern; statt dessen braucht sich der Programmierer lediglich um das Erzeugen der richtigen Folge der Methodenaufrufe und um die Verwendung der richtigen Methode zu kümmern.
- Smalltalk, Java und C++ sind Beispiele von OOP-Sprachen. Smalltalk wurde in den frühen 1970-er Jahren in der Learning Research Group im Xerox Palo Alto Research Center (PARC) entwickelt. C++ wurde 1983 von Bjarne Stroustrup in den AT&T Bell Laboratories als Erweiterung von C entwickelt. Java ist eine OOP-Sprache mit Elementen von C und C++, die hochoptimierte Bibliotheken für die Internetumgebung enthält. Sie wurde bei SUN Microsystems entwickelt und 1995 freigegeben.
- In einem OOP-System verbergen (kapseln) Objekte die interne Struktur ihrer Daten und die von ihren Methoden verwendeten Algorithmen. Anstatt diese Einzelheiten der Realisierung freizulegen, bieten wohlkonstruierte OOP- Objekte Schnittstellen, die ihre Abstraktionen sauber ohne zusätzliche Informationen darstellen. Der Polymorphismus führt die Kapselung einen Schritt weiter. Eine Software-Komponente kann eine Methode in einem OOP-Objekt aufrufen, ohne genaue Einzelheiten darüber zu kennen, wie die Methode arbeitet. Somit kann eine Software-Komponente die 'Zeichen'-Methode für ein Quadratobjekt und für ein Kreisobjekt aufrufen, wobei die Objekte ein Quadrat bzw. einen Kreis zeichnen. Die Vererbung ermöglicht, daß Entwickler eine zuvor existierende Konstruktion und zuvor existierenden Code wiederverwenden, wobei sie die Notwendigkeit verringert, daß Entwickler Software ganz von vorne erzeugen. Statt dessen leiten die Entwickler über die Vererbung Unterklassen ab, die das Verhalten von existierenden OOP-Objekten vererben und die der Entwickler daraufhin anpaßt, so daß ihren besonderen Anforderungen entsprechen.
- Objekte werden anhand von Klassen, die die programmierten Methoden für das Objekt enthalten, in der Halde instanziiert. Instanziierte Objekte enthalten (in Instanzvariablen) Daten, die spezifisch für dieses besondere instanziierte Objekt sind. Allgemein wird ein auf einer Klasse basierendes Objekt instanziiert (oder konstruiert), wenn für das Objekt von der Halde ein Knoten mit Speicher zugeordnet wird, wenn die zum Binden des Objekts an die Klasse benötigten Informationen in dem Objekt gespeichert werden, wenn dem Objekt auch andere geeignete Objekte zugeordnet werden und wenn die Instanzvariablen des Objekts initialisiert werden. Fig. 1d zeigt die konzeptionellen Aspekte eines mit dem allgemeinen Bezugszeichen 170 bezeichneten instanziierten Objekts. Das instanziierte Objekt 170 enthält einen Objekt-Header 171, eine Basisklassen-Variablenablage 173, eine Ablage 175 für Variable der ersten Unterklasse, eine Ablage 177 für Variable der zweiten Unterklasse und eine Ablage 179 für Variable der letzten Unterklasse für die n-te Unterklasse. Der Objekt- Header 171 enthält oder nimmt Bezug auf (mit einem Block 181 bezeichnete) Informationen, die das instanziierte Objekt 170 unterstützen. Die Informationen in dem Objekt- Header 171 enthalten häufig einen Zeiger auf eine Klassendefinition und entweder direkt oder indirekt eine Instanzvariablenzahl. Wie durch den der Ablage 177 für Variable der zweiten Unterklasse zugeordneten Block 183 angegeben ist, enthalten die Basisklassen-Variablenablage 173 und die Ablage 175 für Variable der ersten Unterklasse jeweils Instanzvariable. Die Instanzvariablen in dem Block 183 enthalten gemischte Zeiger- und Datenvariable. Eine Schwierigkeit bei der Organisation der Informationen in dem instanziierten Objekt 170 besteht darin, daß die Datenwert- und Zeigerinstanzvariablen nicht einfach durch Untersuchung der in den Instanzvariablen gespeicherten Informationen unterschieden werden können. Somit ist die Bestimmung der Zeiger auf die Halde zur Speicherbereinigung ineffizient. Diese Ineffizienz hat dazu geführt, daß viele objektorientierte Sprachrealisierungen die Datenwertgenauigkeit opfern und jeden Wert kennzeichnen, um einen Zeigerwert von einem Datenwert zu unterscheiden. Ein weiterer häufiger Zugang stellt eine Kennzeichnungstabelle bereit, die für jede in der Klasse definierte Variable ein Identifizierungskennzeichen zuordnet. Das Identifizierungskennzeichen gibt an, ob die Instanzvariable eines instanziierten Objekts der Klasse einen Datenwert oder einen Zeigerwert enthält. Da bei der Bestimmung der lebenden Knoten in der Halde für jede Instanzvariable die Identifizierungskennzeichentabelle geprüft werden muß, erhöht die Verwendung einer Identifizierungskennzeichentabelle den Rechenorganisationsaufwand. Der Fachmann auf dem Gebiet versteht, daß Zeiger direkt oder indirekt sein können.
- Wie zuvor diskutiert wurde, werden Objekte von der Halde zugeordnet. Somit sind Objekte ein Spezialfall von Knoten. Ferner weisen viele OOP-Realisierungen Objekten einen 'Umsetzwert' zu und stellen Verfahren zum Zugreifen auf diesen Umsetzwert bereit. Der Umsetzwert ist eine nützliche, einem Knoten in der Halde zugeordnete quasieindeutige ganze Zahl. Das Bestimmen dieses Umsetzwerts und dessen Speichern in dem Objekt ist, wenn das Objekt kurzlebig ist (und somit nur für eine begrenzte Zeitdauer in der Halde existiert), ein unnötiger Organisationsaufwand. Ein zum Verringern dieser Last verwendetes Verfahren des Standes der Technik besteht darin, den Umsetzwert nur dann zu erzeugen, wenn er angefordert wird. Somit wird auf einen Zähler zugegriffen, der den nächsten Umsetzwert enthält, um den Umsetzwert zu erhalten, der Umsetzwert in dem Knoten gespeichert und der Zähler inkrementiert, was eine Speicherlese- und zwei Speicherschreiboperationen erfordert.
- Weitere Informationen über OOP-Konzepte sind zu finden in Object Oriented Design with Applications von Grady Booch, die Benjamin/Cummings Publishing Co., Inc., Redwood City, Calif., (1991), ISBN 0-8053-0091-0.
- Programmiersprachen ermöglichen, daß ein Programmierer eine symbolische Textdarstellung (den Quellcode) verwendet, der die Operationen repräsentiert, die eine Anwendungsbinärschnittstelle (ABI) (wie etwa ein Computer oder ein auf einem Computer laufender Interpreter) ausführen soll. Diese symbolische Darstellung wird in Opcodes umgesetzt, die die ABI versteht. Üblicherweise sind diese Opcodes Binärwerte. Compiler erzeugen durch Verarbeiten des Quellcodes eine Objektdatei (oder ein Objektmodul), die die dem Quellcode entsprechenden Opcodes enthält. (Der Fachmann auf dem Gebiet versteht, daß sich die Begriffe 'Objektdatei' und 'Objektmodul' nicht auf das zuvor diskutierte 'OOP-Objekt' beziehen.) Wenn dieses Objektmodul mit anderen Objektmodulen gebunden wird, führt das zu ausführbaren Befehlen, die in einen Computerspeicher geladen und durch die ABI laufengelassen werden können.
- Ein Interpreter ist ein auf einem Computer ausgeführtes Programm, das auf Opcodes zugreift und bewirkt, daß der Computer eine oder mehrere Operationen ausführt, die die durch den Opcode spezifizierte Operation bewirken. Somit kann ein Interpreter gedanklich als ein Programm betrachtet werden, das eine virtuelle Computerumgebung oder eine virtuelle Maschine die ABI - erzeugt. Irgendein Computer, der den Interpreter ausführen kann, kann für die ABI kompilierte Programme ausführen. Somit können die Opcodes des gleichen Programms über ein Netz heruntergeladen werden und auf einer Vielzahl verschiedener Computerarchitekturen, die die ABI realisieren, ausgeführt werden.
- Eine Programmquelle enthält eine geordneten Gruppierung von Zeichenketten (Anweisungen), die sowohl in Opcodes als auch in Daten, die zur Ausführung durch die Ausführungsumgebung geeignet sind, umgesetzt werden. Ein Quellprogramm liefert eine symbolische Beschreibung der Operationen, die die ABI beim Ausführen der Opcodes, die sich aus dem Kompilieren und Binden der Quelle ergeben, ausführt. Die Umsetzung von der Quelle in Opcodes wird gemäß den grammatikalischen und syntaktischen Regeln der zum Schreiben der Quelle verwendeten Programmiersprache ausgeführt.
- Jede kompilierte Anweisung kann mehrere Opcodes erzeugen, die gemäß der ABI die durch die symbolische Anweisung beschriebene Operation realisieren. Ein Compiler kann die durch die Quelle repräsentierte Strukturorganisation beim Erzeugen der kompilierten Opcodes erheblich ändern. Unabhängig davon, wie stark der Compiler die Organisation ändert, ist der Compiler aber dadurch beschränkt, daß die Opcodes, wenn sie durch die ABI laufengelassen werden, das gleiche Ergebnis liefern müssen, das der Programmierer unter Verwendung der Quellsprache beschrieben hat - unabhängig davon, wie dieses Ergebnis erhalten wird. Ähnlich braucht die Reihenfolge, in der Daten in der Struktur gespeichert sind, nicht die gleiche zu sein, wie sie durch die von dem Programmierer gelieferte Folge der Variablendeklarationen realisiert wird. Beispielsweise braucht die tatsächliche Anordnung von Instanzvariablen in einem instanziierten Objekt nicht in der gleichen Reihenfolge zu erfolgen, in der die Variablen in der Klassendeklaration definiert wurden.
- Viele moderne Compiler können die sich aus dem Kompilierungsprozeß ergebenden binären Opcodes optimieren. Wegen der Konstruktion der Computersprachen kann ein Compiler Strukturinformationen über das kompilierte Programm bestimmen. Diese Informationen können durch den Compiler zum Erzeugen verschiedener Versionen der Folge von Opcodes, die die gleiche Operation ausführen, verwendet werden. (Beispielsweise kann die Austestfähigkeit oder können Optimierungsbefehle je nach Version des Zielprozessors, für den der Quellcode kompiliert wird, ermöglicht werden. Einige Optimierungen minimieren die zum Halten der Befehle benötigte Speichermenge; andere Optimierungen verringern die zum Ausführen der Befehle benötigte Zeitdauer.
- Einige Vorteile der Optimierung bestehen darin, daß der Optimierungscompiler den Programmierer von der zeitaufwendigen Aufgabe des manuellen Abstimmens des Quellcodes befreit. Dies erhöht die Produktivität des Programmierers. Optimierungscompiler unterstützen auch, daß ein Programmierer wartungsfähigen Code schreibt, da das manuelle Abstimmen den Quellcode häufig weniger verständlich für andere Programmierer macht. Schließlich verbessert ein Optimierungscompiler die Portierbarkeit des Codes, da ein auf eine Computerarchitektur abgestimmter Quellcode auf einer anderen Computerarchitektur häufig ineffizient sein kann. Eine allgemeine Diskussion von Optimierungscompilern und den verwendeten verwandten Techniken ist zu finden in Compilers: Principles, Techniques and Tools von Alfred V. Aho, Ravi Sethi und Jeffrey D. Ullman, Addison-Wesley Publishing Co., 1988, ISBN 0-201-10088-6, insbesondere in den Kapiteln 9 und 10, S. 513-723.
- Dementsprechend schafft die Erfindung ein Verfahren, eine Vorrichtung und ein Produkt zum Lokalisieren eines Zeigerwerts, wie sie in den beigefügten Ansprüchen genau geschildert sind.
- Die vorliegende Erfindung schafft eine wirtschaftliche Vorrichtung, ein wirtschaftliches Verfahren, ein wirtschaftliches System und ein wirtschaftliches Computerprogrammprodukt zum Schaffen verbesserter Möglichkeiten für Speicherbereinigungsprogramme. Ein Aspekt der Erfindung ist ein computergesteuertes Verfahren zum Lokalisieren eines Zeigerwerts in einer Datenstruktur, die eine Header-Struktur umfaßt. Das Verfahren umfaßt einen Schritt des Konstruierens der Datenstruktur, so daß die Header- Struktur einen Zeiger-Speicherbereich von einem Datenwert-Speicherbereich trennt. Die Header-Struktur enthält einen Header-Wert, der von dem Zeigerwert unterscheidbar ist. Der Header-Wert ist benachbart zu dem Zeiger-Speicherbereich. Das Verfahren umfaßt ferner den Schritt des Abtastens des Zeiger-Speicherbereichs zum Lokalisieren des Zeigerwerts. Außerdem umfaßt das Verfahren den Schritt des Vorwärtsbewegens an der Header-Struktur und an dem Datenwert-Speicherbereich vorbei beim Erfassen des Header-Werts.
- Ein weiterer Aspekt der Erfindung ist eine Vorrichtung mit einer Zentraleinheit, die mit einem Speicher gekoppelt ist und dem Lokalisieren eines Zeigerwerts in einer Datenstruktur in dem Speicher dient. Die instanziierte Objekt-Datenstruktur enthält eine Header-Struktur. Die Vorrichtung umfaßt einen Konstruktionsmechanismus, der so beschaffen ist, daß er die Datenstruktur in dem Speicher konstruiert. Die Header-Struktur in der konstruierten Datenstruktur trennt einen Zeiger-Speicherbereich und einen Datenwert-Speicherbereich. Die Header-Struktur enthält einen Header-Wert, der von dem Zeigerwert unterscheidbar ist. Der Header-Wert ist benachbart zu dem Zeiger-Speicherbereich. Außerdem umfaßt die Vorrichtung einen Abtastmechanismus, der so beschaffen ist, daß er den Zeigerspeicher zum Lokalisieren des Zeigerwerts abtastet. Die Vorrichtung enthält einen Header-Erfassungsmechanismus, der so beschaffen ist, daß er während der Operation des Abtastmechanismus den Header-Wert erfaßt. Außerdem enthält die Vorrichtung einen Vorwärtsbewegungsmechanismus, der so beschaffen ist, daß er in Abhängigkeit von dem Header-Erfassungsmechanismus an der Header-Struktur und an dem Datenwert-Speicherbereich vorbei vorwärtsbewegt.
- Ein nochmals weiterer Aspekt der Erfindung ist ein in ein computernutzbares Medium eingebettetes Computerprogrammprodukt, das bewirkt, daß ein Computer einen Zeigerwert in einer instanziierten Objekt-Datenstruktut in dem Computerspeicher lokalisiert. Wenn der computerlesbare Code auf einem Computer ausgeführt wird, bewirkt er, daß ein Computer einen Konstruktionsmechanismus, einen Abtastmechanismus, einen Header-Erfassungsmechanismus und einen Vorwärtsbewegungsmechanismus ausführt. Jeder dieser Mechanismen besitzt die gleichen Funktionen wie die entsprechenden Mechanismen für die zuvor beschriebene Vorrichtung.
- Die vorstehenden Aspekte der vorliegenden Erfindung werden dem Durchschnittsfachmann auf dem Gebiet nach Lesen der folgenden ausführlichen Beschreibung der in den Fig. 2, 3 und 7 der beigefügten Zeichnung gezeigten bevorzugten Ausführungsformen zweifellos offensichtlich werden. Die Fig. 4, 5, 6 und 8-10 sind lediglich für Referenzzwecke vorgesehen und bilden keinen Teil der vorliegenden Erfindung.
- Fig. 1 zeigt verschiedene Aspekte des Standes der Technik zum Haldensammeln und zur Kartenmarkierung und eine Beispielspeicherstruktur für ein objektorientiertes instanziiertes Objekt;
- Fig. 2 zeigt ein Computersystem, das die Erfindung in Übereinstimmung mit einer bevorzugten Ausführungsform verwenden kann;
- Fig. 3 zeigt Datenstrukturen im Speicher und einen Prozeß unter Verwendung der Datenstrukturen zum Lokalisieren von Zeigern gemäß einer ersten bevorzugten Ausführungsform;
- Fig. 4 zeigt Datenstrukturen im Speicher und einen Prozeß unter Verwendung der Datenstrukturen zum Verarbeiten von Zeigern in einem instanziierten Objekt;
- Fig. 5 zeigt Datenstrukturen im Speicher und Prozesse unter Verwendung der Datenstrukturen zum Initialisieren von Umsetzwerten;
- Fig. 6 zeigt Datenstrukturen im Speicher und Prozesse unter Verwendung der Datenstrukturen zum Erzeugen und Verwenden von Verknüpfungen mit einem Knoten;
- Fig. 7 zeigt Datenstrukturen im Speicher und Prozesse unter Verwendung der Datenstrukturen zum Lokalisieren eines Knoten in einem Kartenspeicherbereich gemäß einer bevorzugten Ausführungsform;
- Fig. 8 zeigt die Kartenmarkierung eines kopierten Haldenbereichs;
- Fig. 9 zeigt Datenstrukturen und Prozesse zur Kartenmarkierung eines Zeigerdatenfelds; und
- Figur. 10 zeigt die Prozesse der Abschnittskartenmarkierung eines Haldenbereichs und der Kartenmarkierung.
- Die folgenden 'Schreibweisen und Nomenklatur' sind als Hilfe beim Verständnis der vorliegenden Erfindung und deren bevorzugter Ausführungsformen vorgesehen.
- Knoten - ein von der Halde zugeordneter Speicherbereich.
- Objekt - ein instanziiertes Objekt liegt in einem Knoten. Es enthält allgemein Instanzvariablen und einen Zeiger auf eine Klasse, die auf die Methoden des Objekts Bezug nimmt.
- Zeiger - ein als Adresse zu einem Knoten verwendeter Wert. Durch Lokalisieren von Zeigern auf Knoten bestimmt ein Speicherbereinigungsalgorithmus, welche Knoten leben.
- Verknüpfung - ein Zeigeräquivalent, das einen Versatz zu dem Erzeugungsbereich und einen Validierungswert, der der Verknüpfung einen Zeiger zuordnet, enthält.
- Prozedur - eine selbstkonsistente Folge von Schritten, die zu einem gewünschten Ergebnis führen. Diese Schritte sind jene, die eine physikalische Manipulation physikalischer Größen erfordern. Üblicherweise nehmen diese Größen die Form elektrischer oder magnetischer Signale an, die gespeichert, übertragen, kombiniert, verglichen und auf andere Weise manipuliert werden können. Diese Signale werden als Bits, Werte, Elemente, Symbole, Zeichen, Ausdrücke, Zahlen oder dergleichen bezeichnet. Für den Fachmann auf dem Gebiet ist selbstverständlich, daß all diese und ähnliche Begriffe den geeigneten physikalischen Größen zugeordnet sind und lediglich auf diese Größen angewandte zweckmäßige Bezeichnungen sind.
- Auf die von einem Computer beim Ausführen von Opcodes ausgeführten Manipulationen wird häufig mit Bezeichnungen wie etwa Addieren oder Vergleichen Bezug zugenommen, die üblicherweise gedanklichen Operationen zugeordnet sind, die von einem menschlichen Betreiber ausgeführt werden. In der vorliegenden Erfindung ist in keiner der hier beschriebenen Operationen eine solche Fähigkeit eines menschlichen Betreibers erforderlich. Die Operationen sind Maschinenoperationen. Nützliche Maschinen zum Ausführen der Operationen der Erfindung umfassen programmierte Universal-Digitalcomputer oder ähnliche Vorrichtungen. In sämtlichen Fällen wird das Verfahren der Berechnung von dem Verfahren der Operation beim Betreiben eines Computers unterschieden. Die vorliegende Erfindung bezieht sich auf Verfahrensschritte zum Betreiben eines Computers beim Verarbeiten elektrischer oder anderer (z. B. mechanischer, chemischer) physikalischer Signale zum Erzeugen anderer gewünschter physikalischer Signale.
- Außerdem bezieht sich die Erfindung auf eine Vorrichtung zum Ausführen dieser Operationen. Diese Vorrichtung kann speziell für die gewünschten Zwecke konstruiert sein oder kann einen Universalcomputer umfassen, der durch ein in dem Speicher eines Computers gespeichertes Computerprogramm selektiv aktiviert oder rekonfiguriert wird. Die hier dargestellten Prozeduren beziehen sich nicht inhärent auf einen besonderen Computer oder auf eine besondere andere Vorrichtung. Insbesondere können verschiedene Universalmaschinen mit in Übereinstimmung mit der hier dargestellten Lehre geschriebenen Programmen verwendet werden oder kann es sich als zweckmäßiger erweisen, eine stärker spezialisierte Vorrichtung zum Ausführen der geforderten Verfahrensschritte zu konstruieren. Für eine Vielzahl dieser Maschinen geht die geforderte Struktur aus der folgenden Beschreibung hervor. Außerdem kann die Erfindung in einem computerlesbaren Ablagemedium ausgeführt sein, das mit einem Programm codiert ist, das bewirkt, daß ein Computer die programmierte Logik ausführt.
- Der Fachmann auf dem Gebiet versteht, daß, obgleich die Figuren und Darstellungen eine besondere Bitordnung in dem Computerspeicherwort verwenden, die tatsächliche Bitordnung für die Erfindung unerheblich ist. Ferner versteht der Fachmann auf dem Gebiet, daß Darstellungen der Datenstrukturen im Speicher oben an der Struktur beim niedriger adressierten Speicher beginnen und zu höher adressiertem Speicher verlaufen.
- In Fig. 2 sind einige der Elemente eines mit dem allgemeinen Bezugszeichen 200 bezeichneten zur Unterstützung der Erfindung konfigurierten Computers gezeigt, wobei ein Prozessor 201 mit einer Zentraleinheit (CPU) 203, einem Speicherabschnitt 205 und einem Eingabe/Ausgabe-Abschnitt (E/A-Abschnitt) 207 gezeigt sind. Der E/A-Abschnitt 207 ist an eine Tastatur 209, an eine Anzeigeeinheit 211, an eine Plattenablageeinheit 213 und an eine CD-ROM-Laufwerkseinheit 215 angeschlossen. Die CD-ROM-Laufwerkseinheit 215 kann ein CD-ROM-Medium 217 lesen, das typischerweise ein Programm und Daten 219 enthält. Eine CD-ROM- Laufwerkseinheit 215 umfaßt zusammen mit dem CD-ROM- Medium 217 und der Plattenablageeinheit 213 einen Dateiablagemechanismus. Ein solches Computersystem kann Anwendungen ausführen, die die Erfindung verkörpern.
- Ein genauer Speicherbereinigungsalgorithmus muß zwischen Werten, die Zeiger sind, und Werten, die keine Zeiger sind, unterscheiden. Wenn die Zeigerwerte lokalisiert sind, können die zugeordneten Knoten in der Halde gefunden werden. Diejenigen Gebiete der Halde, auf die nicht durch diese Zeiger Bezug genommen wird, sind Datenabfall und können durch eine Reinigungsoperation wiedergewonnen werden. Das Lokalisieren der Zeigerwerte verbraucht Computerbetriebsmittel, so daß effizientere Mechanismen vorteilhaft sind.
- Ein Aspekt der Erfindung ist eine geteilte Datenstruktur, die Zeigerwerte von Datenwerten trennt. Wenn dieser Datenstrukturtyp als instanziiertes Objekt verwendet wird, erleichtert er das effiziente Lokalisieren der Zeigerwerte in den Datenstrukturen.
- Fig. 3a zeigt Eine mit dem allgemeinen Bezugszeichen 300 bezeichnete Datenstruktur eines instanziierten Objekts im Speicher, die in der Datenstruktur 300 eines instanziierten Objekts Zeigerwerte von Datenwerten trennt. In Fig. 3a und in sämtlichen anderen Figuren, die Datenstrukturen enthalten, steigen die Speicheradressen beim Abwärtsbewegen in der Struktur. Die Datenstruktur 300 eines instanzijerten Objekts wird aus einer (nicht gezeigten) Klasse abgeleitet. In dem Körper der Datenstruktur 300 eines instanziierten Objekts ist eine Objekt- Header-Struktur 301 angeordnet. Die Objekt-Header-Struktur 301 ist so konstruiert, daß das erste Wort der Objekt-Header-Struktur 301 von einem Zeiger unterscheidbar ist (beispielsweise ist dieser Header-Wert mit dem niederwertigsten Bit des Wortes auf eins gesetzt). Vor der Objekt-Header-Struktur 301 befindet sich ein Zeiger- Speicherbereich 303. Der Zeiger-Speicherbereich 303 enthält die von der Datenstruktur 300 eines instanziierten Objekts verwendeten Zeigerwerte. Hinter der Objekt- Header-Struktur 301 befindet sich ein Datenwert-Speicherbereich 305, der die von dem Objekt verwendeten Nichtzeiger-Datenwerte enthält. Außerdem enthält die Objekt- Header-Struktur 301 oder nimmt Bezug auf ein (nicht gezeigtes) Größenfeld, das die Größe des Datenwert-Speicherbereichs 305 enthält oder dazu verwendet werden kann, sie abzuleiten. In Fig. 3a hat die Datenstruktur 300 eines instanziierten Objekts von einer Unterklasse einer Unterklasse geerbt. Die Basisklassen-Instanzvariablen sind am nächsten bei der Objekt-Header-Struktur 301 angeordnet. Ein Basisklassen-Nichtzeigerinstanz-Variablenbereich 307 wird zum Speichern von Nichtzeiger-Datenwerten für die Basisklasse der Datenstruktur 300 eines instanziierten Objekts verwendet. Ein Basisklassen-Zeigerinstanz- Variablenbereich 309 wird zum Speichern von Zeigerwerten für die Basisklasse der Datenstruktur 300 eines instanziierten Objekts wie etwa eines Zeigers auf eine Tabelle von Methodenprozeduradressen oder Zeigern auf andere Knoten in der Halde verwendet. Auf ähnliche Weise speichern ein Nichtzeigerinstanz-Variablenbereich 311 der ersten Unterklasse bzw. ein Zeigerinstanz-Variablenbereich 313 der ersten Unterklasse Nichtzeiger- und Zeiger- Variablendaten für die erste Unterklasse der Basisklasse. Ähnliches betrifft einen Nichtzeigerinstanz-Variablenbereich 315 der n-ten Unterklasse und einen Zeigerinstanz- Variablenbereich 317 der n-ten Unterklasse. Diese Trennung zwischen Zeiger- und Nichtzeigerdaten wird ferner durch einen Nichtzeigerinstanz-Variablenbereich 319 der zweiten Unterklasse und einen Zeigerinstanz-Variablenbereich 321 der zweiten Unterklassen angegeben, die sich aus der Definition der zweiten Unterklasse ergeben. Eine ausführliche Datenwertzuordnung 323 zeigt den Nichtzeiger-Datenwertbereich, während eine ausführliche Zeigerwertzuordnung 325 den Zeiger-Datenwertbereich zeigt. Somit wird der Prozeß des Bestimmens von Zeigern auf die Halde durch Lokalisieren von Zeigervariablen durch die Trennung von Zeigerwerten und Datenwerten in der Datenstruktur 300 eines instanziierten Objekts vereinfacht.
- Der Fachmann auf dem Gebiet versteht, daß einige Compiler zum Erzeugen der oben offenbarten Objektstruktur möglicherweise abgewandelt werden müssen. Ferner versteht er, daß das Objekt lediglich eine spezielle Verwendung einer Datenstruktur ist und daß das zugrundeliegende Konzept der zuvor beschriebenen Datenstruktur darin besteht, Zeiger vor einem unterscheidbaren Datenstruktur-Header zu speichern, um die Bestimmung der Zeigerinstanzvariablen zu erleichtern. Außerdem versteht er, daß die Trennung des Zeiger-Speicherbereichs 303 und des Datenwert-Speicherbereichs 305 in der Datenstruktur 300 eines instanziierten Objekts bedeutet, daß die Lage einer Instanzvariablen in dem Datenwert-Speicherbereich 305 in bezug auf die Objekt-Header-Struktur 301 für sämtliche instanziierten Objekte anhand der Unterklassen der ursprünglichen Klasse konstant bleibt. Diese Invarianz vereinfacht die Interpretation der Objekte. Für Realisierungen mit kompiliertem Code spart diese Invarianz Platz, indem sie ermöglicht, daß Code, der für eine Unterklasse kompiliert worden ist, für. Instanzen einer Unterklasse der Überklasse wiederverwendet wird.
- Fig. 3b zeigt Einen mit dem allgemeinen Bezugszeichen 350 bezeichneten Prozeß, der zum Sammeln von in einem zusammenhängenden Speichergebiet liegenden Zeigerwerten verwendet wird. Diese Werte werden für die nachfolgende Speicherbereinigungsverarbeitung verwendet. Der Prozeß 350 beginnt bei einem 'Start'-Ausgangspunkt 351 und wird mit einer 'Erhalte-Adresse-des-Gebiets'-Prozedur 353 fortgesetzt. Die 'Erhalte-Adresse-des-Gebiets'-Prozedur 353 erhält die Adresse des nach Zeigern abgetasteten Gebiets und speichert diese Adresse in Ptr. Dieser Speicherbereich beginnt mit dem Zeiger-Speicherbereich 303 des ersten Objekts in dem Gebiet. Nachfolgend bestimmt eine 'Außerhalb-des-Gebiets'-Entscheidungsprozedur 355, ob sich der Ptr über das Ende des Gebiets hinaus vorwärtsbewegt hat. Wenn sich der Ptr über das Ende des Gebiets hinaus vorwärtsbewegt hat, wird der Prozeß 350 über einen 'Ende'-Endpunkt 357 abgeschlossen. Andernfalls wird der Prozeß 350 mit einem 'Setze-'T'-auf-den-Wertauf-den-Ptr-zeigt'-Prozedur 359 fortgesetzt, die den Wert des Platzes, auf den Ptr zeigt, in 'T' speichert. Nachfolgend bestimmt der Prozeß 350 in einer 'Prüfe-'T'-auf- Identifizierungskennzeichen'-Entscheidungsprozedur 361, ob der Wert in. 'T' ein Zeiger oder das erste Wort der Objektdatenstruktur 301 ist. In einer bevorzugten Ausführungsform erfolgt die Bestimmung durch Prüfen der Bits niedriger Ordnung des Wertes, um zwischen den Zeigerwerten in dem Zeiger-Speicherbereich 303 und dem ersten Wort der Objekt-Header-Struktur 301 zu unterscheiden. Wenn die 'Prüfe-'T'-auf-Identifizierungskennzeichen'-Entscheidungsprozedur 361 bestimmt, daß der Wert 'T' ein Zeigerwert ist, wird der Prozeß 350 mit einer 'Verarbeite-'T" - Prozedur 363 fortgesetzt, die den in 'T' gespeicherten Wert je nach Ausführungsform als Zeiger zur nachfolgenden Verarbeitung durch den Speicherbereinigungsprozeß aufzeichnet oder den Speicherbereinigungsprozeß sofort auf den Zeiger anwendet. In einer 'Bewege-Ptr-vorwärts'- Prozedur 365 bewegt der Prozeß 350 daraufhin den Ptr vorwärts, so daß er auf den nächsten Platz in dem Objekt zeigt. Daraufhin wird der Prozeß 350 zu der 'Setze-'T'- auf-den-Wertauf-den-Ptr-zeigt'-Prozedur 359 zurückgeschleift, um das Aufzeichnen von Zeigern in dem Zeiger- Speicherbereich 303 fortzusetzen. Wenn die 'Prüfe-'T'- auf-Identifizierungskennzeichen'-Entscheidungsprozedur 361 aber bestimmt, daß der Wert in 'T' kein Zeiger ist (d. h., daß der Wert in 'T' das erste Wort der Objekt- Header-Struktur 301 ist), wird der Prozeß 350 mit einer 'Bewege-Zeiger-am-Objekt-vorbei-vorwärts'-Prozedur 367 fortgesetzt. Die 'Bewege-Zeiger-am-Objekt-vorbei-vorwärts'-Prozedur 367 bewegt den Ptr mit im Gebiet wohlbekannten Verfahren an dem Datenwert-Speicherbereich 305 und am Rest der Objekt-Header-Struktur 301 vorbei vorwärts.
- Obgleich die vorausgehende Datenstruktur und der vorausgehende Prozeß im Kontext der Abtastung auf Zeiger in einem Speichergebiet beschrieben wurden, versteht der Fachmann auf dem Gebiet, daß eine Ausführungsform Knoten verfolgt, die durch Zeiger aufeinanderbezogen sind, wobei sie das Zeigersipeichergebiet 303 jedes verwandten Knotens abtastet.
- Außerdem versteht der Fachmann auf dem Gebiet, daß viele Techniken zum Vorwärtsbewegen zum nächsten Objekt und zum Addieren von Zeigern zu der Bezugsmenge existieren. Ferner versteht der Fachmann auf dem Gebiet, daß ein Objekt eine spezielle Verwendung einer Datenstruktur ist und daß die obenbeschriebenen Techniken auch auf verallgemeinerte Datenstrukturen im Speicher zutreffen.
- Fig. 4a zeigt Eine mit dem allgemeinen Bezugszeichen 400 bezeichnete Datenstruktur eines instanziierten Objekts, die ähnlich zu dem instanziierten Objekt 170 aus Fig. 1d ist. Die Datenstruktur 400 eines instanziierten Objekts enthält eine Objekt-Header-Struktur 401 und einen Instanzvariablen-Ablagebereich 403. Die Objekt-Header- Struktur 401 enthält einen Klassenzeiger 405, der auf eine Klasse zeigt, die eine mit dem allgemeinen Bezugszeichen 430 bezeichnete Kennzeichnungs-Bitmap enthält.
- Fig. 4b zeigt die in der Klasse enthaltene Kennzeichnungs-Bitmap 430. Die Kennzeichnungs-Bitmap 430 ist eine sequentielle Byte-Anordnung. Jedes Byte unterscheidet für acht aufeinanderfolgende Plätze in dem Instanzvariablen- Ablagebereich 403 für die Datenstruktur 400 eines instanziierten Objekts Zeiger- und Nichtzeigerwerte. Es gibt 256 mögliche Werte, die in einem Byte enthalten sein können. Wie nachfolgend beschrieben wird, dienen die Werte in der Kennzeichnungs-Bitmap 430 als Index auf eine Tabelle von 256 Routineadressen. Diese Werte stellen außerdem Muster von Zeiger- und Nichtzeigerinstanz-Variablen für acht aufeinanderfolgende Instanzvariablen in dem Instanzvariablen-Ablagebereich 403 dar. Beispielsweise enthält die Kennzeichnungs-Bitmap 430 unter der Annahme, daß der Instanzvariablen-Ablagebereich 403 zwölf Werte enthält, drei Einträge: einen ersten Eintrag 431, einen zweiten Eintrag 433 und einen dritten Eintrag 435. Unter der weiteren Annahme, daß der neunte, der fünfzehnte und der zwanzigste Wert in dem Instanzvariablen-Ablagebereich 403 Zeigerwerte sind, ist der Wert des ersten Eintrags 431 gleich null, der Wert des zweiten Eintrags 433 gleich 41(hex) und der Wert des dritten Eintrags 435 gleich 08 (hex).
- Fig. 4c zeigt eine mit dem allgemeinen Bezugszeichen 450 bezeichnete Routine-Absende-Tabelle. Die Routine-Absende- Tabelle 450 enthält Zeiger, Zugriffsnummern oder ähnliche Einrichtungen zum Aufrufen aufgerufener Routinen. Jede aufgerufene Routine empfängt, wenn Sie aufgerufen wird, als Argument einen Zeiger auf die momentane Variable in dem Instanzvariablen-Ablagebereich 403. Ein erster Eintrag 451 in der Routine-Absende-Tabelle 450 enthält einen Zeiger auf eine Prozedur, die keine Instanzvariablen in dem Instanzvariablen-Ablagebereich 403 verarbeitet. Der erste Eintrag 451 entspricht einem Eintrag in der Kennzeichnungs-Bitmap 430, der keine Zeiger in den nächsten acht Variablen des Instanzvariablen-Ablagebereichs 403 angibt. Ein zweiter Eintrag 453 in der Routine-Absende- Tabelle 450 enthält einen Zeiger auf eine aufgerufene Routine zum Verarbeiten von INDEX(0) 455. Diese aufgerufene Routine 455 verarbeitet nur die Variable in dem Instanzvariablen-Ablagebereich 403, auf die das übergebene Argument zeigt. Ein dritter Eintrag 457 in der Routine-Absende-Tabelle 450 enthält einen Zeiger auf eine aufgerufene Routine zum Verarbeiten von INDEX(3) 459, die über die Variable, auf die das übergebene Argument zeigt, hinaus nur die dritte Instanzvariable verarbeitet. Ein vierter Eintrag 461 in der Routine-Absende-Tabelle 450 enthält einen Zeiger auf eine aufgerufene Routine zum Verarbeiten von INDEX(0) und INDEX(6) 463. Diese Routine 463 verarbeitet sowohl die Variable, auf die das übergebene Argument zeigt, als auch die sechste Variable nach der Variablen, auf die das übergebene Argument zeigt. Schließlich enthält ein fünfter Eintrag 465 in der Routine-Absende-Tabelle 450 einen Zeiger auf eine aufgerufene Routine zum Verarbeiten von INDEX(0) bis INDEX(7) 467. Diese Routine 467 verarbeitet sämtliche acht Instanzvariablen, beginnend bei der Instanzvariablen, auf die das übergebene Argument zeigt. Somit verarbeitet jede aufgerufene Routine ein Muster von Zeiger- und Nichtzeigerinstanz-Variablen, das bei dem übergebenen Argument beginnt.
- Die aufgerufenen Routinen 455, 459, 463 und 467 enthalten eine programmierte Logik zum Verarbeiten der Zeiger für die nächsten bis zu acht Variablen in der Datenstruktur 400 eines instanziierten Objekts. Somit verarbeitet ein Speicherbereinigungsverfahren effizient die Zeiger in dem Instanzvariablen-Ablagebereich 403 der Datenstruktur 400 eines instanziierten Objekts. Die Speicherbereinigungsprozedur erledigt dies dadurch, daß sie, anstatt die Identifizierungskennzeichen für jede Variable zu testen, direkt auf eine Prozedur zugreift, die bekannte Muster von Zeigervariablen verarbeitet. Somit wird der variablenweise Prozeß des Standes der Technik, der jede Variable prüft, um zu bestimmen, ob die Variable einen Zeiger enthält, durch eine Prozedur ersetzt, die acht bekannte Variablen gleichzeitig prüft, ohne jede Variable zu prüfen.
- Nachfolgend wird die aufrufende Prozedur zum Aufrufen der aufgerufenen Routinen 455, 459, 463, 467 beschrieben. Der Fachmann auf dem Gebiet versteht, daß je nach Ausführungsform entweder die aufgerufene Routine oder die aufrufende Prozedur den Zeiger in den Instanzvariablen- Ablagebereich 403 vorwärtsbewegen kann. Die aufgerufenen Routinen 455, 459, 463, 467 fügen entweder die spezifizierten Zeiger zu der Bezugsmenge hinzu oder führen an den spezifizierten Zeigern andere Speicherbereinigungsaufgaben auf.
- Fig. 4d zeigt einen mit dem allgemeinem Bezugszeichen 470 bezeichneten Prozeß, der die aufrufende Prozedur realisiert, die zum Absenden der zum Verarbeiten der Zeiger auf den Instanzvariablen-Ablagebereich 403 verwendeten aufgerufenen Routinen 455, 459, 463, 467 verwendet wird. Der Prozeß 470 wird an einem 'Start'-Ausgangspunkt 471 begonnen und mit einer Prozedur 473 fortgesetzt. Die Prozedur 473 erhält einen Zeiger auf die in der Klasse liegende Kennzeichnungs-Bitmap 430. Nachfolgend wird der Prozeß mit einer Prozedur 475 fortgesetzt, die unter Verwendung der Größe des Instanzvariablen-Ablagebereichs 403 die Anzahl der Einträge in der Kennzeichnungs-Bitmap 430 bestimmt. Daraufhin initialisiert die Prozedur 477 einen Zeiger auf den Instanzvariablen-Ablagebereich 403. Nachfolgend wird der Prozeß 470 mit einer Iterationsprozedur 479 vorwärtsbewegt, die über die Einträge in der Kennzeichnungs-Bitmap 430 iteriert. Nach Abschluß der Iterationsprozedur 479 wird der Prozeß 470 über einen 'Ende'-Endpunkt 481 abgeschlossen. Für jede über die Iterationsprozedur 479 gesteuerte Iteration liest eine 'Lies-Bitmap-aus'-Prozedur 483 den Bitmap-Eintrag für die momentane Iteration aus der Kennzeichnungs-Bitmap 430 aus. Nachfolgend indiziert eine Absendeprozedur 485 über den Bitmap-Eintrag auf die Routine-Absende-Tabelle 450 und ruft eine Routine auf, die den Zeiger auf den Instanzvariablen-Ablagebereich 403 übergibt. Wenn die aufgerufene Routine zurückspringt, wird der Prozeß 470 über die Iterationsprozedur 479 mit nächsten Iteration fortgesetzt. Der Fachmann auf dem Gebiet erkennt, daß die aufgerufene Prozedur oder die aufrufende Prozedur den Variablenzeiger vorwärtsbewegen kann.
- Die aufgerufenen Routinen 455, 459, 463, 467 führen an den spezifizierten Zeigern die entsprechenden Speicherbereinigungsaufgaben aus. Der Fachmann auf dem Gebiet versteht außerdem, daß zahlreiche Techniken zum Spezifizieren der Länge der Kennzeichnungs-Bitmap 430 existieren. Diese Techniken umfassen, sind aber nicht beschränkt auf, das Anordnen der Länge der Kennzeichnungs-Bitmap 430 in dem Objekt, in der Objektklasse oder das Aufnehmen der Länge in die Kennzeichnungs-Bitmap 430.
- Wie zuvor diskutiert wurde, ist ein Umsetzwert eine nützliche, einem Knoten zugeordnete quasieindeutige ganze Zahl. Ein Umsetzwert wird für den Knoten einmal erzeugt und ändert sich während der Lebensdauer des Knotens nicht. Häufig sind solche Knoten instanziierte OOP-Objekte. Somit liefert das Objekt allgemein eine Ablage für den Umsetzwert und eine OOP-Methode zum Zurückgeben des Umsetzwerts des Objektes. Der Fachmann auf dem Gebiet versteht, daß die gleiche Funktionalität unter Verwendung von Datenstrukturen in Knoten und durch das Vorsehen eines verfahrensorientierten Zugriffs auf den Inhalt der Datenstruktur realisiert werden kann. Eingedenk dessen, daß die Lebensdauer eines Objekts für viele OOP-Anwendungen sehr begrenzt ist (d. h., daß die meisten Objekte in dem Erzeugungsbereich erzeugt werden und dort sterben), stellt der Organisationsaufwand zum Erzeugen des Umsetzwerts für Objekte in dem Erzeugungsbereich eine Belastung dar.
- Fig. 5a zeigt einen mit dem allgemeinen Bezugszeichen 500 bezeichneten Erzeugungsbereich. Der Erzeugungsbereich 500 enthält einen Erzeugungsbereich 501, der einen Knoten 503 enthält. Nachdem der Knoten 503 zugeordnet wurde, besitzt er eine Knotendresse. Diese Knotenadresse ist in einem Knotenzeiger 505 enthalten (andernfalls wäre der Knoten 503 Datenabfall). Der Umsetzwert für den Knoten 503 wird unter Verwendung des Inhalts der Knotenadresse und einer 'Globaler-Umsetzversatz'-Variablen 507 bestimmt. Der Inhalt der 'Globaler-Umsetzversatz'-Variablen 507 wird anfangs auf null gesetzt. Nach jeder Reinigungsoperation in dem Erzeugungsbereich 501 wird der Inhalt der 'Globaler-Umsetzversatz'-Variablen 507 um die Größe des Erzeugungsbereichs 501 erhöht. Jedesmal, wenn auf den Erzeugungsbereich 501 eine Reinigungsoperation angewendet wird, werden sämtliche aktiven Knoten in einen anderen Erzeugungsbereich des (nicht gezeigten) Haldenspeichers kopiert. Somit ist der Erzeugungsbereich 501 nach einer Reinigungsoperation leer. Der Umsetzwert des Knotens 503 wird durch Addieren der in dem Knotenzeiger 505 enthaltenen Knotenadresse zu dem Inhalt der 'Globaler-Umsetzversatz'-Variablen. 507 bestimmt. Während der Reinigungsoperation ändert sich der Wert der 'Globaler-Umsetzversatz'- Variablen 507 beim Berechnen des Umsetzwerts für den kopierten Knoten nicht. Die einzige auf die 'Globaler- Umsetzversatz'-Variable 507 gerichtete Speicherschreiboperation findet nicht während jeder Umsetzerzeugung, sondern am Ende der Reinigungsoperation statt - was viele Speicherzugriffe spart.
- Fig. 5b zeigt eine mit dem allgemeinen Bezugszeichen 510 bezeichnete 'get_hash'-Prozedur, die den Umsetzwert erzeugt. Die 'get_hash'-Prozedur 510 beginnt bei einem 'Start'-Ausgangspunkt 511 und wird mit einer Entscheidungsprozedur 513 fortgesetzt, die bestimmt, ob der Umsetzwert in dem Objekt gespeichert ist. In einer bevorzugten Ausführungsform kann der Umsetzwert nicht null sein, so daß die Umsetzwert-Instanzvariable, wenn das Objekt zugeordnet wird, auf null initialisiert wird. Falls der Inhalt der Umsetzwert-Instarizvariablen nicht null ist, wird die 'get_hash'-Prozedur 510 mit einer 'Gib-gespeicherten-Umsetzwert-zurück'-Prozedur 515, die den Umsetzwert von der Instanzvariablen des Objekts zurückgibt, fortgesetzt und die 'get_hash'-Prozedur 510 über einen 'Ende'-Endpunkt 517 abgeschlossen. Falls aber der Inhalt der Umsetzwert-Instanzvariablen des Objekts in der Entscheidungsprozedur 513 null ist, wird die 'get_hash'-Prozedur 510 mit einer 'Berechne-Umsetzwert- und-gib-ihn-zurück'-Prozedur 519 fortgesetzt. Die 'Berechne-Umsetzwert-und-gib-ihn-zurück'-Prozedur 519 addiert die in dem Knotenzeiger 505 enthaltene Adresse des Objekts zu dem Inhalt der 'Globaler-Umsetzversatz'-Variablen 507. Die 'Berechne-Umsetzwert und-gib-ihn-zurück'- Prozedur 519 gibt dieses Ergebnis zurück. Nachfolgend wird die 'get_hash'-Prozedur 510 über den 'Ende'-Endpunkt 517 abgeschlossen. Somit wird die Verarbeitung zur Bestimmung des Umsetzwerts verzögert, bis der Umsetzwert tatsächlich benötigt wird. Da die meisten Knoten in dem Erzeugungsbereich 501 sterben, ohne daß auf sie jemals wegen ihres Umsetzwerts zugegriffen wird, ist die Objektzuordnung effizienter als die Techniken des Standes der Technik. Der Fachmann auf dem Gebiet versteht, daß die 'get_hash'-Prozedur 510 in dem OOP-Kontext (in dem der Knoten 503 ein OOP-Objekt ist) eine OOP-Methode für das Objekt ist.
- Fig. 5c zeigt eine mit dem allgemeinen Bezugszeichen 520 bezeichnete 'Kopiere-aktive-Knoten-aus-dem-Erzeugungsbereich'-Prozedur. Die 'Kopiere-aktive-Knoten-aus-dem- Erzeugungsbereich'-Prozedur 520 kopiert aktive Knoten aus dem Erzeugungsbereich 501 in den (nicht gezeigten) Haldenbereich einer älteren Generation. Die 'Kopiere-aktive- Knoten-aus-dem-Erzeugungsbereich'-Prozedur 520 beginnt bei einem 'Start'-Ausgangspunkt 521 und wird mit einer Iterationsprozedur 523, die über sämtliche lebenden Knoten in dem Erzeugungsbereich 501 iteriert, fortgesetzt. Wenn sämtliche lebenden Knoten iteriert worden sind, wird der Prozeß mit einer 'Aktualisiere-Umsetzversatz'-Prozedur 525, die die Größe des Erzeugungsbereichs 501 zu dem Inhalt der 'Globaler-Umsetzversatz'-Variablen 507 addiert, fortgesetzt. Daraufhin wird die 'Kopiereaktive-Knoten-aus-dem-Erzeugungsbereich'-Prozedur 520 über einen 'Ende'-Endpunkt 527 abgeschlossen. Bei jeder Iteration der Iterationsprozedur 523 kopiert eine 'Kopiere-das-Objekt-das-den-berechneten-Umsetzwert-speichert'-Prozedur 531 den Knoten aus dem Erzeugungsbereich in eine ältere Generation. Die 'Kopiere-Objekt-das-denberechneten-Umsetzwert-speichert'-Prozedur 531 berechnet außerdem den Umsetzwert und speichert den berechneten Umsetzwert während des Kopierens des Knotens in dem kopierten Knoten. Somit ist über die zum Kopieren des Knotens benötigten Speicherschreiboperationen hinaus keine zusätzliche Speicherschreiboperation erforderlich. Daraufhin stellt eine 'Zeigerbuchführung'-Prozedur 533 existierende Zeiger auf den früheren Platz des Knotens in der Weise ein, daß sie auf den neuen Platz des Knotens zeigen, der nun in der älteren Generation liegt. Nachfolgend wird die 'Kopiere-aktive-Knoten-aus-dem-Erzeugungsbereich'-Prozedur 520 mit der Iterationsprozedur 523 zum Verarbeiten des nächsten lebenden Objekts fortgesetzt. Somit wird der Organisationsaufwand zum Erzeugen des Umsetzwerts für ein Objekt hinausgeschoben, bis das Objekt in eine ältere Generation kopiert wird oder bis das Objekt aufgefordert wird, seinen Umsetzwert zurückzugeben, während es in dem Erzeugungsbereich 501 liegt. Entweder die 'Kopiere-aktive-Knoten-aus-dem-Erzeugungsbereich'-Prozedur 520 oder die 'get_hash'-Prozedur 510 löst eine Umsetzungserzeugungsbedingung aus, die den Umsetzwert erzeugt.
- Insbesondere dann, wenn es viele kurzlebige Knoten gibt, die Umsetzwerte benötigen, ist der Prozeß aus Fig. 5 effizienter als der des Standes der Technik. Er ist effizienter, da der Inhalt der 'Globaler-Umsetzversatz'- Variablen 507 anstatt wie vom Stand der Technik gefordert während jeder Umsetzwertberechnung aus dem Speicher geladen und im Speicher gespeichert zu werden, nur bei jeder Reinigung aktualisiert wird. Ferner ersetzt die zum Speichern des Umsetzwerts in dem Objekt benötigte Speicherschreiboperation die zum Kopieren dieses Feldes des Knotens benötigte Speicherschreiboperation. Somit wird zum Speichern des Umsetzwerts in dem Knoten kein Speicherzugriff mit zusätzlichem Organisationsaufwand verwendet.
- Da die Größe des Erzeugungsbereichs im Vergleich zum Rest der Halde klein ist, bedeutet das, daß auf die Gesamtheit des Erzeugungsbereichs durch einen Versatz mit einer begrenzten Feldlänge zu dem Erzeugungsbereich zugegriffen werden kann. Somit kann (unter der Annahme einer Wortausrichtung in einer Vier-Byte-adressierbaren Computerarchitektur) eine Verknüpfung mit einem Knoten in einem Ein- Megabyte-Erzeugungsbereich mit nur achtzehn Bits eines Worts spezifiziert werden. Während ein Zeiger in 32-Bit- Computern 32 Bits verwendet, kann eine Verknüpfung achtzehn Bits als Wortindex auf den Erzeugungsbereich und vierzehn Bits als Validierungswert verwenden. Der Validierungswert wird zur Angabe nicht aktualisierter Zugriffe auf den Erzeugungsbereich nach Reinigen des Erzeugungsbereichs, aber vor Abschluß sämtlicher Zeiger- und Verknüpfungsaktualisierungen verwendet. Unter der Annahme einer ausreichend großen Zeigergröße werden Verknüpfungen und Zeiger durch das höchstwertige Bit (MSB) des Wertes unterschieden. Das MSB für einen Zeiger ist null, während das für eine Verknüpfung eins ist.
- Fig. 6a zeigt einen mit dem allgemeinen Bezugszeichen 600 bezeichneten Erzeugungsbereich, auf den mit einer Verknüpfung Bezug genommen wird, mit einem Erzeugungsbereich 601, der einen Knoten 603 enthält. Dem Erzeugungsbereich 601 ist ein Bereichsvalidierungswert 605 zugeordnet, der den Validierungswert für die momentane Reinigungsoperation des Erzeugungsbereichs 601 enthält. In jeder Reinigungsoperation wird zunächst der Bereichsvalidierungswert 605 auf null initialisiert und daraufhin der Bereichsvalidierungswert 605 inkrementiert. Eine Verknüpfung 607 enthält ein 'Verknüpfungsversatz'-Feld 609 und ein 'Verknüpfungsvalidierung'-Feld 611. Das 'Verknüpfungsversatz'-Feld 609 enthält einen zum Spezifizieren des Knotens 603 verwendeten Versatz zu dem Erzeugungsbereich 601. Das 'Verknüpfungsvalidierung'-Feld 611 enthält eine Kopie des Inhalts der Validierungsvariablen für den Erzeugungsbereich 601 zu dem Zeitpunkt, zu dem die Verknüpfung 607 erzeugt wurde (d. h. zu dem Zeitpunkt, zu dem der Knoten zugeordnet wurde). Eine Erzeugungsbasisadresse 613 enthält die Adresse des Anfangs des Erzeugungsbereichs 601. Ein Gleichheitsvergleich 615 führt einen Gleichheitsvergleich zwischen dem Inhalt des Bereichsvalidierungswerts 605 und dem Inhalt des 'Verknüpfungsvalidierung'-Feldes 611 aus. Wenn die Verknüpfung 607 zur Bezugnahme auf den Knoten 603 geliefert wird, werden somit die Inhalte des 'Verknüpfungsvalidierung'-Feldes 611 und des Bereichsvalidierungswerts 605 auf Gleichheit verglichen. Wenn der Inhalt des Bereichsvalidierungswerts 605 und der des 'Verknüpfungsvalidierung'-Feldes 611 gleich sind, werden das 'Verknüpfungsversatz'-Feld 609 und die Erzeugungsbasisadresse 613 durch eine Additionsoperation 617 summiert, um die Adresse des Knotens 603 zu erhalten. Wenn aber der Inhalt des 'Verknüpfungsvalidierung'-Feldes 611 und der des Bereichsvalidierungswerts 605 verschieden sind, ist der Erzeugungsbereich 601 nach Konstruktion der Verknüpfung 607 gereinigt worden - womit der Knoten 603 aus dem Erzeugungsbereich 601 in einen (nicht gezeigten) Zeigerbezugnahme-Haldenbereich kopiert wurde. Wie nachfolgend beschrieben wird, befindet sich unter diesen Umständen der neue Platz des Knotens 603 in dem Zeigerbezugnahme- Haldenbereich, wobei die Verknüpfung in einen Zeiger umgesetzt ist.
- Fig. 6b zeigt eine mit dem allgemeinen Bezugszeichen 620 bezeichnete Verknüpfungs-Zeiger-Umsetztabelle. Die Verknüpfungs-Zeiger-Umsetztabelle 620 ist in Zeilen mit Spalten organisiert. Jede Zeile enthält Daten mit Bezug auf einen aus dem Erzeugungsbereich 601 kopierten Knoten. Die Spalten enthalten ein 'Verknüpfungsvalidierung'-Feld 621, ein 'Verknüpfungsversatz'-Feld 623 und ein 'Knotenzeiger'-Feld 625. Wenn der Knoten 603 in dem Erzeugungsbereich 601 erzeugt wurde, enthält das 'Verknüpfungsvalidierung'-Feld 621 den Validierungswert für den Knoten 603. Wenn der Knoten 603 in dem Erzeugungsbereich 601 erzeugt wurde, enthält das 'Verknüpfungsversatz'-Feld 623 den Verknüpfungsversatzwert für den Knoten 603. Das 'Knotenzeiger'-Feld 625 enthält einen Zeiger (die momentane Adresse) auf den kopierten Knoten. Somit enthält ein erster Eintrag 627 einen Eintrag, der einem vor der Reinigung '1' erzeugten Knoten 'A', der sich an einem Wortversatz von '15' vom Start des Erzeugungsbereichs 601 befand und nun an dem durch das 'Knotenzeiger'-Feld 625 des ersten Eintrags 627 spezifizierten Platz befindet, eine Verknüpfung zuordnet. Ähnliches gilt für einen zweiten Eintrag 629, aber für den Knoten 'Z'. Ein dritter Eintrag 631 ordnet einem Knoten 'W', der nach der Reinigung '1', aber vor der Reinigung '2' erzeugt wurde, der sich bei einem Wortversatz von '15' von dem Anfang des Erzeugungsbereichs 601 befand und nun an dem durch das 'Knotenzeiger'-Feld 625 des dritten Eintrags 631 spezifizierten Platz befindet, eine Verknüpfung zu. Es wird angemerkt, daß das 'Verknüpfungsversatz'-Feld 623 für den ersten Eintrag 627 und für den zeeiten Eintrag 631 gleich ist. Somit wurden die beiden Knoten 'A' und 'W' am gleichen Platz in dem Erzeugungsbereich 601, aber zu verschiedenen Zeiten (wie durch die verschiedenen Werte in dem 'Verknüpfungsvalidierung'-Feld 621 gezeigt ist) zugeordnet. Der Fachmann auf dem Gebiet versteht, daß viele mögliche Strukturen zur Ausführung dieser Tabelle existieren. Diese umfassen ohne Beschränkung eine zusammenhängende Tabelle für sämtliche Einträge, verknüpfte Tabellen für jeden Wert des 'Verknüpfungsvalidierung'- Feldes 621 und viele andere dem Fachmann auf dem Gebiet bekannte Organisationen.
- Fig. 6c zeigt Einen mit dem allgemeinen Bezugszeichen 640 bezeichneten Verknüpfungszugriffsprozeß, der zum Zugreifen auf einen Knoten ausgehend von einer Verknüpfung mit dem Knoten verwendet wird. Der Verknüpfungszugriffsprozeß 640 beginnt bei einem 'Start'-Ausgangspunkt 641 und wird mit einer Entscheidungsprozedur 643 fortgesetzt, die bestimmt, ob der Inhalt des 'Verknüpfungsvalidierung'- Feldes 611 der Verknüpfung mit dem Inhalt des Bereichsvalidierungswerts 605 für den Erzeugungsbereich 601 übereinstimmt. Wenn der Inhalt des 'Verknüpfungsvalidierung'- Feldes 611 und der des Bereichsvalidierungswerts 605 übereinstimmen, wird der Prozeß mit einer 'Zugriff-auf- Knoten-im-Erzeugungsbereich'-Prozedur 645, die einen Zugriff auf den in dem Erzeugungsbereich 601 gespeicherten Knoten schafft, fortgesetzt. Dieser Zugriff wird dadurch geschaffen, daß ein Zeiger auf den Knoten erzeugt wird, indem das 'Verknüpfungsversatz'-Feld 609 zu der Erzeugungsbasisadresse 613 addiert wird, um einen Zeiger auf den Knoten zu konstruieren. Nachfolgend wird der Verknüpfungszugriffsprozeß 640 über einen 'Ende'-Endpunkt 647 abgeschlossen. Wenn aber in der Entscheidungsprozedur 643 der Inhalt des 'Verknüpfungsvalidierung'-Feldes 611 und der des Bereichsvalidierungswerts 605 nicht übereinstimmen, ist der Knoten aus dem Erzeugungsbereich kopiert worden. In dieser Situation wird der Prozeß mit einer 'Passe-Validierung-an'-Prozedur 649 fortgesetzt, die die Verknüpfungs-Zeiger-Übersetzungstabelle 620 nach einer Übereinstimmung zwischen dem 'Verknüpfungsvalidierung'- Feld 621 in der Verknüpfungs-Zeiger-Umsetzungstabelle 620 und dem 'Verknüpfungsvalidierung'-Feld 611 der gelieferten Verknüpfung durchsucht. Wenn eine Übereinstimmung gefunden wird, wird der Verknüpfungszugriffsprozeß 640 mit einer 'Passe-Versatz-an'-Prozedur 651 fortgesetzt, die das 'Verknüpfungsversatz'-Feld 623 der Verknüpfungs- Zeiger-Übersetzungstabelle 620 nach einem mit dem Inhalt des 'Verknüpfungsversatz'-Feldes 609 übereinstimmenden Eintrag durchsucht. Wenn der übereinstimmende Eintrag in der Verknüpfungs-Zeiger-Übersetzungstabelle 620 gefunden worden ist, wird der Verknüpfungszugriffsprozeß 640 mit einer 'Erhalte-Knotenzeiger'-Prozedur 653 vorwärtsbewegt, die den Zeiger auf den kopierten Knoten aus dem 'Knotenzeiger'-Feld. 625 des übereinstimmenden Eintrags in der Verknüpfungs-Zeiger-Übersetzungstabelle 620 ausliest. Dieser ausgelesene Zeiger wird zum Zugreifen auf den kopierten Knoten in dem Zeigerbezugnahme-Haldenbereich verwendet. Nachfolgend wird der Verknüpfungszugriffsprozeß 640 mit einer 'Aktualisiere-Bezugnahme'-Prozedur 655 vorwärtsbewegt, die die Knotenbezugnahme aus der Verknüpfungsform in die Zeigerform aktualisiert, indem sie bewirkt, daß die bezugnehmende Prozedur die gespeicherte Verknüpfung auf den Knoten durch den Zeiger auf den Knoten ersetzt. Der Verknüpfungszugriffsprozeß 640 wird über den 'Ende'-Endpunkt 647 abgeschlossen.
- Der Fachmann auf dem Gebiet versteht, daß die Verwendung von Verknüpfungen auf Bezugsknoten, die in dem Erzeugungsbereich 601 liegen oder gelegen haben, ermöglicht, daß der Zeigeraktualisierungsteil der Reinigungsoperation unterbrochen wird. Somit können Echtzeitsysteme, die nicht die zum vollständigen Aktualisieren sämtlicher Bezugnahmen auf einen aus dem Erzeugungsbereich 601 kopierten Knoten benötigte Zeit verbrauchen können, in der verfügbaren Zeitdauer die Bezugnahmen auf kopierte Knoten teilweise aktualisieren, ohne das Echtzeitwesen der Anwendung zu unterbrechen. Wie zuvor beschrieben wurde, wird selbst während der Zeitdauer, während der der Aktualisierungsprozeß unterbrochen wird, eine Verknüpfungsbezugnahme auf einen kopierten Knoten erfaßt und die Bezugnahme auf eine direkte Zeigerbezugnahme auf den kopierten Knoten geändert.
- Einer der Hauptvorteile der Generations-Speicherbereinigertechniken besteht darin, daß sie lediglich Knoten untersuchen, die zur Reinigungszeit noch leben. Bei Verwendung schwacher Zeiger geht dieser Vorteil aber verloren. Schwache Zeiger sind solche, die auf Knoten Bezug nehmen, ohne die Lebensdauer der Knoten, auf die Bezug genommen wird, zu beeinflussen. Die Speicherbereinigungstechniken des Standes der Technik realisieren schwache Zeiger als direkte Zeiger. Um sicherzustellen, daß keine Bezugnahme eines schwachen Zeigers auf einen freigewordenen Knoten die Reinigung überlebt, müssen somit zur Reinigungszeit sämtliche freigewordenen Knoten durchsucht werden. Diese. Suche wirkt sich auf den zuvor erwähnten Vorteil der Generations-Speicherbereinigungstechniken aus.
- Verknüpfungen können dagegen verwendet werden, um schwache Zeiger zu realisieren, die auf Knoten Bezug nehmen, ohne die Lebensdauer der Knoten, auf die Bezug genommen wird, zu beeinflussen. Diese Realisierung ermöglicht den ursprünglichen Vorteil, daß lediglich Knoten abgetastet werden, die die Abtastung überleben. Knoten, die nicht überleben, besitzen keinen entsprechenden Eintrag in der Verknüpfungs-Zeiger-Übersetzungstabelle. Eine Verknüpfung, die keinen Eintrag in der Verknüpfungs-Zeiger- Übersetzungstabelle besitzt, ist einfach ein speicherbereinigter Knoten. Schwache Bezugnahmen, die auf Datenabfall zeigen, ermöglichen, daß die Datenabfallknoten, wann immer es zweckmäßig ist, erneut zugeordnet werden.
- Fig. 6d zeigt eine mit dem allgemeinen Bezugszeichen 660 bezeichnete Teilknotenliste. Die Teilknotenliste 660 enthält mehrere Knotendeskriptoren 661, 663, 665, 667. Jeder Knotendeskriptor enthält einen 'Nächster-Deskriptor'-Zeiger 669, d. h. einen Zeiger auf den nächsten Knotendeskriptor der Teilknotenliste 660. Außerdem enthält jeder Knotendeskriptor eine aktive Knotenverknüpfung 671, die eine Verknüpfung mit einem lebenden. Knoten oder mit einem Datenabfallknoten in der Halde enthält. Außerdem enthält jeder Knotendeskriptor ein 'Knoteninformation'-Feld 673, das zusätzliche Informationen über den verknüpften Knoten enthält. Diese Informationen enthalten typischerweise den Status und die Größe des verknüpften Knotens. Der Knotendeskriptor 661 nimmt auf einen ersten aktiven Knoten 675 Bezug. Ähnliches gilt für den Rest der mehreren Knotendeskriptoren 663, 665, 667, die auf einen zweiten aktiven Knoten 677, auf einen Datenabfallknoten 679 und auf einen dritten aktiven Knoten 681 Bezug nehmen. Auf den Datenabfallknoten 679 wird durch den Knotendeskriptor 665 Bezug genommen, wobei der Speicherbereinigungsprozeß, da in einer aktiven Knotenverknüpfung 683 anstelle eines direkten Zeigers eine Verknüpfung gespeichert ist, auf den Datenabfallknoten 679 Bezug nehmen kann, ohne die Lebendigkeit des Datenabfallknotens 679 zu beeinflussen.
- Eine Kartenmarkierung ist nützlich zur Angabe interessanter Bereiche der Halde. Schreibsperrentechniken geben an, welche Karten modifiziert worden sind, und helfen so durch Begrenzen der Menge der Halde, die geprüft werden muß, das Auffinden modifizierter Zeiger zu optimieren.
- Die Kartenmarkierung kann außerdem verwendet werden, um anzugeben, welche Knoten in einer älteren Generation Zeiger auf die jüngere Generation enthalten. Somit kann ein besonderer Kartenbereich der Halde mehrere Markierungsvektoren besitzen, die jeweils für einen besonderen Zweck angepaßt sind.
- Fig. 7a zeigt eine mit dem allgemeinen Bezugszeichen 700 bezeichnete Kartenmarkierungsstruktur, die zum Bestimmen des Platzes einer Knotenbezugnahme in einem Karten-Haldenspeicherbereich 701 verwendet wird. In einer bevorzugten Ausführungsform ist die Knotenbezugnahme der Anfang des Knotens. In einer weiteren bevorzugten Ausführungsform ist die Knotenbezugnahme der Knoten-Header. Da der Speicherbereinigungsprozeß zum Lokalisieren von Zeigern in den Karten in dem Knoten gespeicherte Informationen verwenden muß, ist es bei einer gegebenen markierten Karte nützlich, den Anfang oder Header eines Knotens zu bestimmen. Diese Zeiger werden häufig zu der Wurzelmenge hinzugefügt. Nachfolgende Knoten in einer Karte werden unter Verwendung des Knotenvorwärtsbewegungswerts gefunden. Dieser Knotenvorwärtsbewegungswert wird zum Vorwärtsbewegen zu der Knotenbezugnahme in dem nächsten Knoten zu dem Platz der Knotenbezugnahme addiert. Die folgende Diskussion verwendet den Anfang des Knotens als die Knotenbezugnahme und die Knotengröße als den Knotenvorwärtsbewegungswert. In Fig. 7a sind mehrere in dem Karten-Haldenspeicherbereich 701 verteilte Knoten 703, 705, 707, 709 gezeigt. Ein 'Knotenanfang'-Vektor 711 gibt an, welche Karten in dem Karten-Haldenspeicherbereich 701 die Anfangsgrenze eines Knotens enthalten. In einer ersten bevorzugten Ausführungsform wird diese Angabe in einem Bit pro Karte in dem 'Knotenanfang'-Vektor 711 gespeichert. Da somit in Fig. 7a die Anfangsgrenze des vierten Knotens 709 in einer Karte 713 liegt, wird ein entsprechender Eintrag 715 in dem 'Knotenanfang'-Vektor 711 eingestellt. Da eine Karte 717 keine Anfangsgrenze enthält, ist ein entsprechender Eintrag 719 in dem 'Knotenanfang'-Vektor 711 leer. Der Fachmann auf dem Gebiet versteht, daß die Werte des 'Knotenanfang'-Vektors 711 anstelle der Knotengrenze auch den Platz des Knoten- Headers enthalten können. Dieser Zugang kann bei Knoten verwendet werden, die wie etwa in bezug mit Fig. 3 beschrieben eine verzweigte Datenstruktur enthalten.
- Entsprechend jeder Header-Karte in dem 'Knotenanfang'- Vektor 711 gibt es ein in einer 'Knotenversatz'-Struktur 721 enthaltenes Feld, das einen Versatz vom Anfang der zugeordneten Karte zu der ersten Knotengrenze in der Karte enthält. In dieser bevorzugten Ausführungsform ist das Feld ein Byte-Feld, womit die Kartenlänge bis zu 256 adressierbare Speichereinheiten (typischerweise Wörter) betragen kann. Beispielsweise enthält ein der Karte 713 zugeordnetes 'Knotenversatz'-Feld 723 einen Wert '112'. Somit befindet sich 112 Wörter vom Anfang der Karte 713 die erste Knotengrenze - die des vierten Knotens 709.
- Falls die Knoten die Knotengröße enthalten und eine Angabe enthalten, welche Variablen in dem Knoten Zeiger enthalten, können, wenn der Anfang des ersten Knotens in der Karte gefunden worden ist, nachfolgende Knoten untersucht werden, um Zeiger zu sammeln. Somit verwendet der Prozeß ausgehend von einer markierten Karte, die einen Geändert-Zeiger oder einen Alt-Neu-Zeiger in einer Karte bezeichnet, den 'Knotenanfang'-Vektor 711 und die 'Knotenversatz'-Struktur 721, um die Knoten, die sich mit der markierten Karte überschneiden, schnell zu lokalisieren und zu verarbeiten.
- Fig. 7b zeigt eine mit dem allgemeinen Bezugszeichen 730 bezeichnete Kartenmarkierungsstruktur in einer Ausführungsform, in der die 'Knotenversatz'-Struktur 721 und der 'Knotenanfang'-Vektor 711 aus Fig. 7a in einer 'Komprimierter-Knotenversatz'-Struktur 731 zusammengefaßt sind. Der Karten-Haldenspeicherbereich 701, der erste Knoten 703, der zweite Knoten 705, der dritte Knoten 707 und der vierte Knoten 709 sind in Fig. 7b (bis auf die Größe der Karten) die gleichen wie in Fig. 7a. In dieser Ausführungsform enthält die 'Komprimierter-Knotenversatz- Struktur 731 Byte-Felder, die die Funktionen des 'Knotenanfang'-Vektors 711 und der in Fig. 7a gezeigten 'Knotenversatz'-Struktur 721 verknüpfen. Eine Folge dieser Ausführungsform besteht darin, daß die Karten anstelle der 256 oder mehr durch die Kartenmarkierungsstruktur 700 in Fig. 7a zulässigen Speichereinheiten nun auf höchstens 128 adressierbare Speichereinheiten (wieder typischerweise Wörter) beschränkt sind. In dieser Ausführungsform gibt ein Wert von bis zu 127 an, daß eine Karte eine Knotengrenze enthält, wobei dies die erste Knotengrenze in der Karte spezifiziert. Karten, die keine Knotengrenze enthalten, sind mit einem Wert von 128 angegeben. Somit gibt ein Wert von 112 in einem kombinierten Knotenversatz- und Knotengrenzen-Angabefeld 733 an, daß die Karte 713 eine Knotengrenze enthält, wobei er die erste Knotengrenze in der Karte spezifiziert. Ein Wert von 128 in einem kombinierten Knotenversatz- und Knotengrenze-Angabefeld 735 gibt an, daß die Karte 717 keine Knotengrenze enthält.
- Fig. 7c zeigt einen mit dem allgemeinen Bezugszeichen 750 bezeichneten Knotenlokalisierungsprozeß. Der Knotenlokalisierungsprozeß 750 beginnt bei einem 'Start'-Ausgangspunkt 751 und wird mit einer 'Erhalte-Index-der-markierten-Karte'-Prozedur 753 fortgesetzt. Die 'Erhalte-Indexder-markierten-Karte'-Prozedur 753 empfängt entweder den Zeiger, der eine Adresse in einem Knoten enthält, und erzeugt aus der Adresse einen Kartenindex oder empfängt einfach einen Index einer markierten Karte oder irgendeinen anderen Kartenidentifizierer, Daraufhin wird beginnend bei dem früheren Index und unter Abtastung des 'Knotenanfang'-Vektors 711 in einer 'Finde-Knotengrenzein-früherer-Karte'-Prozedur 755 auf den 'Knotenanfang'- Vektor 711 zugegriffen, bis eine Karte gefunden wird, die eine Knotengrenze enthält. Der Fachmann auf dem Gebiet versteht, wie die 'Finde-Knotengrenze-in-früherer-Karte'- Prozedur 755 für Schreibsperrenrealisierungen zu modifizieren ist, die anstelle der modifizierten Karte die Karte markieren, die die Knotengrenze enthält. Daraufhin wird der Lokalisierungsprozeß 750 mit einer 'Erhalte- Versatz-zur-ersten-Knotengrenze-in-der-Karte'-Prozedur 757, die den zugeordneten Versatz der Grenze des ersten Knotens in der Karte ausliest, fortgesetzt. Daraufhin folgt auf die Knoten eine 'Taste-nach-vorn-ab-um-denrelevanten-Knoten-zu-finden'-Prozedur 759 nach vorn, bis der Knoten, der die markierte Karte schneidet, gefunden ist. Nachfolgend werden in einer 'Verarbeite-Knoten'- Prozedur 761 die Zeiger im Knoten verarbeitet. Die nachfolgenden Zeiger in der Karte werden ebenfalls verarbeitet. Schließlich wird der Knotenlokalisierungsprozeß 750 über einen 'Ende'-Endpunkt 763 abgeschlossen.
- Somit findet die Erfindung ausgehend von einer gegebenen Adresse in einem Kartenspeicherbereich oder von dem Kartenindex schnell diejenigen Knoten, die Zeiger mit Bezug auf eine markierte Karte enthalten.
- Wie zuvor mit Bezug auf Fig. 1c beschrieben worden ist, besteht ein Ziel der Kartenmarkierung bei Verwendung mit einem Generations-Speicherbereinigungsalgorithmus im Überspringen von Objekten in dem Bereich der kopierten Generation der Halde, die nicht auf Objekte in dem Erzeugungsbereich der Halde Bezug nehmen. Dieses Ziel wird aber verfehlt, wenn die Dichte dieser Knoten in der älteren Generation so beschaffen ist, daß die meisten Karten markiert sind.
- Fig. 8a zeigt eine mit dem allgemeinem Bezugszeichen 800 bezeichnete Kartenmarkierungsstruktur, die sich aus dem erfindungsgemäßen Bearbeiten der in Fig. 1c gezeigten 'Kartenmarkierungsstruktur' 140 ergibt. Ein jüngerer Bereich der Halde 801 enthält wenigstens einen Knoten 803, 805, 807. Ein älterer Bereich der Halde 809 ist in mehrere Karten 811, 813 geteilt. Der Karte 811 ist eine Kartenmarkierung 815 zugeordnet, während der Karte 813 eine Kartenmarkierung 817 zugeordnet ist. Eine Kartengrenze 819 gibt das Ende der Karte 811 und den Anfang der Karte 813 an. Der Bereich der Halde 809 für die ältere Generation enthält eine 'Anzahl der Knoten (A-F)' 821 mit einem 'Knoten E' 823 und einem 'Knoten C' 825. In der Kartenmarkierungsstruktur 800 enthält der 'Knoten E' 823 einen Zeiger auf den Knoten 805, während der 'Knoten C' 825 einen Zeiger auf den Knoten 803 enthält, die beide in dem jüngeren Bereich der Halde 801 liegen. Die Kartenmarkierung 815 ist markiert, da ein Knoten in der Karte 811 auf den jüngeren Bereich der Halde 801 Bezug nimmt. In diesem Beispiel nimmt sowohl der 'Knoten E' 823 als auch der 'Knoten C' 825 auf den jüngeren Bereich der Halde 801 Bezug. Da kein Knoten in der Karte 813 auf den jüngeren Bereich der Halde 801 Bezug nimmt, ist die Kartenmarkierung 817 nicht markiert. Somit wird das Ziel der Kartenmarkierung durch Lokalisieren der Knoten in dem Bereich der Halde 809 für die ältere Generation, die Zeiger auf den jüngeren Bereich der Halde 801 enthalten, erreicht.
- Fig. 8b zeigt einen mit dem allgemeinem Bezugszeichen 850 bezeichneten Knotensammelprozeß. Der Knotensammelprozeß 850 beginnt bei einem 'Start'-Ausgangspunkt 851 und wird mit einer Iterationsprozedur 853 fortgesetzt. Die Iterationsprozedur 853 iteriert über die markierten Karten derjenigen Generation, die gerade gesammelt wird. In einer 'Zeigerknoten-Sammel'-Prozedur 855 wird jeder Knoten oder Teilknoten, der einen Zeiger auf eine jüngere Generation erhält, gesammelt. Der Fachmann auf dem Gebiet kann Knoten behandeln, die Kartengrenzen überqueren. Eine 'Erinnere-an-Nichtzeiger-Knoten'-Prozedur 857 erinnert an jeden Knoten in der Karte, der keinen Zeiger auf eine jüngere Generation besitzt. Der Prozeß wird mit der Iterationsprozedur 853 zurück fortgesetzt, bis sämtliche markierten Karten verarbeitet sind. Somit werden sämtliche Knoten in der Generation, die Zeiger auf eine jüngere Generation besitzen, wie in Fig. 8a gezeigt im Speicher lokalisiert. Der Fachmann auf dem Gebiet versteht, daß die Sammelprozedur die geeigneten Karten für die kopierte Generation markiert. Nachfolgend wird der Prozeß mit einer 'Sammle-Knoten-an-die-erinnert-wurde'-Prozedur 859, die diejenigen Knoten sammelt, an die während der 'Erinnere-an-Nichtzeiger-Knoten'-Prozedur 857 erinnert wurde, fortgesetzt. Diese Knoten enthalten keine Zeiger auf eine jüngere Generation und brauchen somit lediglich in den Bereich der kopierten Generation übertragen zu werden. Nachfolgend wird in einer Iterationsprozedur 861 jede nicht markierte Karte untersucht. Jeder Knoten in der nicht markierten Karte wird durch eine 'Sammle-Knoten-inder-Karte'-Prozedur 863 gesammelt. Der Prozeß wird über die Iterationsprozedur 861 iteriert, bis sämtliche nicht markierten Karten verarbeitet sind. Schließlich wird der Prozeß über einen 'Ende'-Endpunkt 865, der die Kartenmarkierungsstruktur 800 aus Fig. 8a verläßt, abgeschlossen.
- Eine weitere Möglichkeit, die Effizienz des Lokalisierens von Zeigern in einer kartenmarkierten Halde zu verbessern, besteht darin, zusätzliche Informationen für Datenstrukturen vorzusehen, die Zeiger enthalten. Insbesondere spezifizieren diese zusätzlichen Informationen, welche Variablen in der Datenstruktur durch eine Programmschleife, die eine Schleifensteuervariable als Index auf ein Datenfeld von Datenstrukturen verwendet, geändert worden sind. Ferner verbessert dies die Effizienz der Schleifen dadurch, daß die Schreibsperrenbefehle, die den Zuweisungsoperationen der Zeigerwerte zu einem Zeigerdatenfeld zugeordnet sind, aus dem Innern des Iterationsteils der Schleife herausgenommen werden. Somit verbessert dies die Ausführungsgeschwindigkeit des Programms beim Zuweisen von Werten zu einem Zeigerdatenfeld in einer kartenmarkierten Halde. Ein weiterer Aspekt verbessert die Wirksamkeit der Speicherbereinigungsoperation des Lokalisierens modifizierter Zeiger in der kartenmarkierten Halde.
- Fig. 9a zeigt ein mit dem allgemeinen Bezugszeichen 900 bezeichnetes kartenmarkiertes Gebiet des Speichers mit einer kartenmarkierten Halde 901. Die kartenmarkierte Halde 901 enthält eine Zeigerdatenfeldstruktur 903, deren Anfang in einer Karte 905 liegt. Da ein Zeigerwert in der Kartendatenfeldstruktur 903 während der Ausführung einer Schleife modifiziert worden ist, wird die Kartenmarkierung 907 wie nachfolgend beschrieben markiert.
- Fig. 9b zeigt eine mit dem allgemeinem Bezugszeichen 910 bezeichnete Zeigerdatenfeldstruktur. Die Zeigerdatenfeldstruktur 910 enthält einen Datenfeld-Header 911 und einen Datenfeld-Datenbereich 912. Der Datenfeld-Header 911 wird zum Parametrisieren der in dem Datenfeld-Datenbereich 912 enthaltenen Zeigerdaten verwendet und enthält ein 'Erster'-Feld 913, ein 'Letzter'-Feld 915, ein 'Schritt'- Feld 917 und ein 'Zeigerdatenfeld-Initialisierung'-Feld 919. Der Datenfeld-Datenbereich 912 enthält ein 'Erster- Datenfeldzeiger'-Element 921 und ein 'Letzter-Datenfeldzeiger'-Element 923, die die anderen Zeigerelemente in der Zeigerdatenfeldstruktur 910 umgeben. Das 'Erster'- Feld 913 enthält den Index des ersten Elements, das sich in dem Datenfeld-Datenbereich 912 geändert hat. Das 'Letzter'-Feld 915 enthält den Index des letzten Elements, das sich in dem Datenfeld-Datenbereich 912 geändert hat. Das 'Schritt'-Feld 917 enthält den Schritt zwischen jedem der geänderten Elemente in dem Datenfeld- Datenbereich 912. Das 'Zeigerdatenfeld-Initialisierung' - Feld 919 enthält die Anfangswerte des 'Erster'-Feldes 913. Die Informationen in dem 'Zeigerdatenfeld-Initialisierung'-Feld 919 werden zum Zurücksetzen des 'Erster'- Feldes 913 nach Abschluß einer Reinigungsoperation in der kartenmarkierten Halde 901 verwendet. Der Anfangswert für das 'Erster'-Feld 913 ist der maximale Datenfeldindex. Der Anfangswert für das 'Letzter'-Feld 915 ist null. Der Anfangswert für das 'Schritt'-Feld 917 ist ebenfalls null. Diese Felder werden nach einer Reinigungsoperation auf ihre Anfangswerte zurückgesetzt.
- Eine 'for'-Anweisung in 'C' (und ähnliche Schleifenanweisungen in anderen Programmiersprachen) enthält einen Anfangsindex, einen Endindex und einen Schritt. Die 'for'-Anweisung weist einer Steuervariablen den Anfangsindex zu. Der Schritt wird bei jeder Iteration der 'for'- Anweisung zu dieser Steuervariablen addiert, bis die Steuervariable den Endindex erreicht, wobei die 'for'- Anweisung an diesem Punkt abgeschlossen wird. Somit liefert eine Zeigerzuweisung zu einem Element der durch die Steuervariable in einer solchen Iterationsanweisung indizierten Zeigerdatenfeldstruktur 910 ein Muster der Zeigerzuweisungen in der Zeigerdatenfeldstruktur 910. Dieses Muster wird von dem Speicherbereinigungsalgorithmus beim Abtasten der Halde auf Zeiger verwendet. Der Fachmann auf dem Gebiet versteht, daß die Erfindung nicht nur für die 'for'-Anweisung, sondern auch für allgemeine Schleifenkonstrukte nützlich ist.
- Fig. 9c zeigt einen mit dem allgemeinen Bezugszeichen 930 bezeichneten 'Markiere-Zeigerdatenfeld'-Prozeß, der von einem ausgeführten Programm verwendet wird, um den Datenfeld-Header 911 für eine Schleife, die auf die Zeigerdatenfeldstruktur 910 zugreift, dynamisch zu modifizieren. Die Anfangsbedingungen beim Eintritt in diesen Prozeß lauten, daß die Zeigerdatenfeldstruktur 910 existiert und daß der Datenfeld-Header 911 initialisiert worden ist und möglicherweise durch vorausgehende Schleifenoperationen an der Zeigerdatenfeldstruktur 910 modifiziert worden ist. Der 'Markiere-Zeigerdatenfeld'-Prozeß 930 verwendet drei Variable: eine Variable "A", die die aus den Anfangswerten des Datenfeld-Headers 911 erhaltenen Werte "A.First, A.Last und A.Stride" erhält; eine Variable "C", die die aus dem Muster der Schleifenzuweisungen der momentanen Schleife erhaltenen Werte "C.First, C.Last und C.Stride" erhält; und eine Variable "M", die die Werte "M.First, M.Last und M.Stride", die das Ergebnis der Vereinigung der Variablen "A" und "C" sind, enthält. Die Variable "A" ist einfach der Datenfeld-Header 911. Die Variable "M" wird schließlich während des 'Markiere- Zeigerdatenfeld"-Prozesses 930 in dem Datenfeld-Header 911 gespeichert.
- Der 'Markiere-Zeigerdatenfeld'-Prozeß 930 wird bei einem 'Start'-Ausgangspunkt 931 begonnen und mit einer 'Initialisiere-C'-Prozedur 932 fortgesetzt. Die 'Initialisiere- C'-Prozedur 932 speichert den Anfangsindex, den Endindex und den Schritt, die von der momentanen Schleife verwendet werden, in der Variablen "C". Eine 'Markiere-Halde- als-inkonsistent'-Prozedur 933 markiert nachfolgend denjenigen Speicherbereich, der die Zeigerdatenfeldstruktur 910 enthält, als inkonsistent. Das Markieren des Haldenbereichs als inkonsistent verhindert, daß der Speicherbereinigungsprozeß den Bereich während der Ausführung der Schleife zu reinigen versucht. Außerdem setzt die 'Markiere-Halde-als-inkonsistent'-Prozedur 933, nachdem die Halde als inkonsistent markiert worden ist, den Kartenmerker 907, um anzugeben, daß in der bei der Karte 905 beginnenden Zeigerdatenfeldstruktur 903 ein Zeigerplatz geändert worden ist. Nachfolgend setzt eine 'Setze-M.First'-Prozedur 935 M.First auf das Minimum von A.First und C.First. Daraufhin setzt eine 'Setze-M.Last'- Prozedur 937 M.Last auf das Maximum von A.Last und C.Last. Der 'Markiere-Zeigerdatenfeld'-Prozeß 930 wird mit einer Entscheidungsprozedur 939 fortgesetzt, die erfaßt, ob der Wert von A.Stride nicht gleich dem Wert von C.Stride ist. Wenn diese Werte nicht gleich sind, wird der 'Markiere-Zeigerdatenfeld'-Prozeß 930 mit einer 'Setze-M.Stride-auf-1'-Prozedur 941, die M.Stride auf den Wert "eins" initialisiert, fortgesetzt. Andernfalls geht der 'Markiere-Zeigerdatenfeld'-Prozeß 930 zu einer 'Setze-M.Stride-auf-A.Stride'-Prozedur 943, die M.Stride auf den Wert von A.Stride initialisiert. Unabhängig davon, ob die 'Setze-M.Stride-auf-1'-Prozedur 941 oder die 'Setze-M.Stride-auf-A.Stride'-Prozedur 943 ausgeführt wird, wird der 'Markiere-Zeigerdatenfeld'-Prozeß 930 mit einer Schleifenprozedur 945 fortgesetzt. Die Schleifenprozedur 945 führt an der Zeigerdatenfeldstruktur 910 die Schleifenoperation aus. Nachfolgend speichert eine 'Aktualisiere-A'-Prozedur 947 die modifizierten Werte in der Variablen "M" zurück in dem Datenfeld-Header 911. Der Fachmann auf dem Gebiet versteht, daß die 'Aktualisiere- A'-Prozedur 947 vor Ausführung der Schleifenprozedur 945 ausgeführt worden sein könnte. Daraufhin markiert eine 'Markiere-Halde-als-konsistent'-Prozedur 949 die Halde als konsistent, um zu ermöglichen, daß der Speicherbereinigungsprozeß den Bereich reinigt. Schließlich wird der 'Markiere-Zeigerdatenfeld'-Prozeß 930 über einen 'Ende'- Endpunkt 951 abgeschlossen. Der Fachmann auf dem Gebiet versteht, daß mehrere Schleifen mit. Zuordnungen der Zeiger zu der Zeigerdatenfeldstruktur 910 den Datenfeld- Header 911 dynamisch aktualisieren und somit parametrisieren, welche Elemente in dem Datenfeld-Datenbereich 912 zwischen den Reinigungsoperationen modifiziert werden.
- Fig. 9d zeigt einen mit dem allgemeinen Bezugszeichen 960 bezeichneten Compiler-Optimierungsprozeß. Der Compiler- Optimierungsprozeß 960 wird während der Optimierungsphase eines Compilers ausgeführt. Er modifiziert den in Fig. 9c beschriebenen 'Markiere-Zeigerdatenfeld'-Prozeß 930 für einige üblicherweise verwendete Schleifen, die zum Zugreifen auf ein Datenfeld mit einer unteren Grenze und mit einer oberen Grenze verwendet werden. Die Schleife besitzt die Deskriptoren C.First, C.Last und C.Stride. Der Compiler-Optimierungsprozeß 960 beginnt bei einem 'Start'-Ausgangspunkt 961 und wird mit einer Entscheidungsprozedur 963, die C.First mit der unteren Grenze des Datenfelds, auf das gerade zugegriffen wird (A.LowerBound) vergleicht, fortgesetzt. Wenn das erste Element des Datenfelds, auf das die Schleife zugreift, gleich dem ersten Element des Datenfelds ist, wird der Compiler-Optimierungsprozeß 960 mit einer 'Optimiere- Schritt-735'-Prozedur 965 fortgesetzt, die Code für die Zielanwendung erzeugt, der M.First auf die untere Grenze des Datenfelds (A.LowerBound) setzt und somit die nicht optimierte Minimumoperation auf eine einzelne Zuweisung reduziert. Unabhängig von den Ergebnissen der Entscheidungsprozedur 963 wird der Compiler-Optimierungsprozeß 960 mit einer Entscheidungsprozedur 967 fortgesetzt, die C.Last mit der oberen Grenze des Datenfelds, auf das gerade zugegriffen wird (A.UpperBound) vergleicht. Wenn das letzte Element des Datenfelds, auf das durch die Schleife zugegriffen wird, gleich dem letzten Element in dem Datenfeld ist, wird der Compiler-Optimierungsprozeß 960 mit einer 'Optimiere-Schritt-737'-Prozedur 969 fortgesetzt, die Code für die Zielanwendung erzeugt, der M.Last auf die obere Grenze des Datenfelds (A.UpperBound) setzt und somit die nicht optimierte Maximumoperation auf eine einfache Zuweisung reduziert. Unabhängig von den Ergebnissen der Entscheidungsprozedur 967 wird der Compiler-Optimierungsprozeß 960 mit einer Entscheidungsprozedur 971 fortgesetzt, die C.Stride mit dem Wert eins vergleicht. Wenn C.Stride gleich dem Wert eins ist, wird der Compiler-Optimierungsprozeß 960 mit einer 'Optimiere- Schritt-739-743'-Prozedur 973 fortgesetzt, die Code für die Zielanwendung erzeugt, der den Wert von M.Stride anstelle der Verwendung der Schritte 739, 741 und 743 auf den Wert eins setzt und somit den 'Markiere-Zeigerdatenfeld'-Prozeß 930 optimiert. Unabhängig von den Ergebnissen der Entscheidungsprozedur 971 wird der Compiler- Optimierungsprozeß 960 über einen 'Ende'-Endpunkt 975 abgeschlossen.
- Fig. 9e zeigt einen mit dem allgemeinen Bezugszeichen 980 bezeichneten Datenfeld-Reinigungsprozeß. Der Datenfeld- Reinigungsprozeß 980 wird mit einem 'Start'-Ausgangspunkt 981 begonnen, wenn der Speicherbereinigungsprozeß eine Karte mit einem modifizierten Zeigerdatenfeld erfaßt hat. Der Datenfeld-Reinigungsprozeß 980 empfängt einen Zeiger auf die Zeigerdatenfeldstruktur 910 und wird mit einer 'Initialisiere-Schleife'-Prozedur 983 fortgesetzt. Die 'Initialisiere-Schleife'-Prozedur 983 liest die Informationen über die modifizierten Zeiger in der Zeigerdatenfeldstruktur 910 aus dem Datenfeld-Header 911 aus. Nachfolgend durchläuft eine 'Durchlaufe-Schleife-über-das- Datenfeld'-Prozedur 985 eine Schleife über die durch den Datenfeld-Header 911 spezifizierten Zeiger. Wenn die 'Durchlaufe-Schleife-über-das-Datenfeld'-Prozedur 985 abgeschlossen ist, wird der Datenfeld-Reinigungsprozeß 980 mit einer 'Setze-Datenfeld-Header-zurück'-Prozedur 987, die die Felder in dem Datenfeld-Header 911 auf ihren Anfangszustand zurücksetzt, fortgesetzt. Zu diesem Zeitpunkt wird auch der Kartenmerker 907 gelöscht, um anzugeben, daß in der Zeigerdatenfeldstruktur 910 keine unverarbeiteten Zeigermodifizierungen existieren. Daraufhin wird der Datenfeld-Reinigungsprozeß 980 über einen 'Ende'-Endpunkt 989 abgeschlossen. Jede Iteration der 'Durchlaufe-Schleife-über-das-Datenfeld'-Prozedur 985 führt eine 'Verarbeite-Zeiger'-Prozedur 991 aus, die den iterierten Zeiger gemäß den Erfordernissen des Speicherbereinigungsalgorithmus verarbeitet.
- Der Kartenmarkierungsspeicher eines Kartenhaldenspeichergebiets ist wesentlich kleiner als der Kartenhaldenspeicherbereich selbst. Allerdings kann der Organisationsaufwand zum Abtasten des Kartenmarkierungsspeichers für einen großen Kartenhaldenspeicher sehr hoch sein. Dieser Organisationsaufwand wird verringert, wenn nur Abschnitte des Kartenmarkierungsspeichers abgetastet zu werden brauchen. Der Kartenmarkierungsspeicher kann in Abschnitte unterteilt werden. Diese Abschnitte werden durch ein Statusbit gekennzeichnet, um anzugeben, daß ein durch den Abschnitt gesteuerter Kartenmerker markiert worden ist. Nur die Kartenmerker in den mit Merkern versehenen Abschnitten werden abgetastet.
- Fig. 10a zeigt eine mit dem allgemeinen Bezugszeichen 1000 bezeichnete Kartenmarkierungsstruktur mit einem Karten-Haldenspeicherbereich 1001, der mehrere Karten 1003, 1005, 1007, 1009 enthält. Die erste modifizierte Karte 1003 und die zweite modifizierte Karte 1005 sind nach der letzten Reinigungsoperation Ziel einer Schreiboperation gewesen. Die erste nicht modifizierte Karte 1007 und die zweite nicht modifizierte Karte 1009 hatten nach der letzten Reinigung keine Schreiboperation. Dem Karten-Haldenspeicherbereich 1001 ist ein Kartenvektor 1011, d. h. der Kartenmarkierungsspeicher, zugeordnet. Dem Kartenvektor 1011 ist seinerseits ein Abschnittsvektor 1013 zugeordnet. Der Abschnittsvektor 1013 enthält einen 'Abschnitt-'Z"-Eintrag 1015 und einen 'Abschnitt- 'Z + 1"-Eintrag 1017.
- Der Kartenvektor 1011 enthält einen Merker 1019 für die erste markierte Karte, einen Merker 1021 für die zweite markierte Karte und einen Merker 1023 für die erste nicht markierte Karte. Dem Merker 1019 für die erste markierte Karte ist die erste modifizierte Karte 1003 zugeordnet. Der Merker 1021 für die zweite markierte Karte ist die zweite modifizierte Karte 1005 zugeordnet. Dem Merker 1023 für die erste nicht markierte Karte ist die erste nicht modifizierte Karte 1007 zugeordnet.
- Dem 'Abschnitt-'Z"-Eintrag 1015 ist ein 'Abschnitt-'Z"- Teil 1025 des Kartenvektors 1011 zugeordnet. Dem 'Abschnitt-'Z + 1"-Eintrag 1017 ist ein 'Abschnitt- 'Z + 1"-Teil 1027 des Kartenvektors 1011 zugeordnet, der einen Merker 1029 für eine zweite nicht markierte Karte enthält und der der zweiten nicht markierten Karte 1009 zugeordnet ist.
- Somit hat der Kartenvektor 1011 unter der Annahme, daß der Kartenhaldenspeicherbereich 1001 eine Größe von 2²&sup6; Wörtern hat und daß jede Karte eine Größe von 2&sup8; Wörtern hat, eine Größe von 2¹&sup8; Bytes, Unter der Annahme, daß jeder Abschnitt in dem Abschnittsvektor 1013 2¹² Bytes einschließt, werden zum Einschließen des Kartenhaldenspeicherbereichs 1001 lediglich 2&sup6; Abschnitte benötigt. Somit kann unter Umständen, in denen der Kartenhaldenspeicherbereich 1001 in der Weise organisiert ist, daß Speicher, der wahrscheinlich modifiziert wird, zusammen lokalisiert ist, erhebliche Verarbeitungszeit dadurch eingespart werden, daß zunächst der Abschnittsvektor 1013 nach Abschnitten abgetastet wird, für die ein Merker gesetzt ist, um anzugeben, daß eine dem Abschnitt zugeordnete Karte markiert ist.
- Fig. 10b zeigt eine mit dem allgemeinen Bezugszeichen 1030 bezeichnete Abschnittsstruktur. Die Abschnittsstruktur 1030 ist jedem Abschnitt (wie etwa dem 'Abschnitt- 'Z"-Eintrag 1015) in dem Abschnittsvektor 1013 zugeordnet. Ein 'Abschnitts-R/W-Status'-Feld 1031 enthält den Lese-Schreib-Status des Abschnitts. Der Inhalt des 'Abschnitts-R/W-Status'-Feldes 1031 ist entweder Lesen- Schreiben oder Nur-Lesen. Das 'Abschnitts-R/W-Status'- Feld 1031 enthält einen Nur-Lese-Status, wenn angenommen wird, daß der Inhalt des dem Teil des Kartenvektors 1011 für den Abschnitt zugeordneten Kartenhaldenspeicherbereichs 1001 selten auf den Erzeugungsbereich Bezug nimmt. Diesem Nur-Lese-Attribut ist ein hardwaregestützter Nur- Lese-Schutz für den durch die Abschnittsstruktur 1030 gesteuerten Teil des Kartenvektors 1011 zugeordnet. Somit wird die Schreiboperation in den Kartenmerker durch die Hardware abgefangen, wenn eine Schreibsperre während einer Schreiboperation in den Kartenspeicher eine Karte zu markieren versucht. Die Hardware meldet dann einen Speicherzugriffsfehler. Wie nachfolgend beschrieben wird, wird die Erfindung über den Schreibversuch benachrichtigt, wobei sie Operationen an der Abschnittsstruktur 1030 ausführt, das 'Abschnitts-R/W-Status'-Feld 1031 als Lesen-Schreiben markiert und den Schreibzugriff auf den durch die Abschnittsstruktur 1030 gesteuerten Teil des Kartenvektors 1011 ermöglicht. Der Speicherbereinigungsprozeß tastet den Abschnittsvektor 1013 auf jene Abschnitte ab, deren 'Abschnitts-R/W-Status'-Feld 1031 einen Lese-Schreib-Status enthält. Wenn das 'Abschnitts- R/W-Status'-Feld 1031 einen Nur-Lese-Status enthält, untersucht der Speicherbereinigungsprozeß den durch die Abschnittsstruktur 1030 gesteuerten Teil des Kartenvektors 1011 nicht - und spart somit Zeit während des Speicherbereinigungsprozesses. Außerdem enthält die Abschnittsstruktur 1030 ein 'Zuletzt-modifiziert-Zeit'-Feld 1033, das angibt, wann der der Abschnittsstruktur 1030 zugeordnete Speicher zuletzt modifiziert worden ist. Das 'Zuletzt-modifiziert-Zeit'-Feld 1033 bezieht sich auf Reinigungszyklen. Ein 'Zeiger-auf-die-erste-Karte-im-Abschnitt'-Feld 1035 ist ein Zeiger auf den ersten der Abschnittstruktur 1030 zugeordneten Kartenmerker in dem Kartenvektor 1011. Ein 'Anzahl-der-Karten-im-Abschnitt'- Feld 1037 enthält die Anzahl der durch die Abschnittsstruktur 1030 gesteuerten Karten. Ein 'Herunterzähl- Zeitgeber'-Feld 1039 enthält einen Herunterzähl-Zeitgeber, der nach jeder Reinigungsoperation dekrementiert wird.
- Fig. 10c zeigt einen mit dem allgemeinen Bezugszeichen 1050 bezeichneten 'Markiere-Abschnitt'-Prozeß. Der 'Markiere-Abschnitt'-Prozeß 1050 beginnt an einem 'Start'- Ausgangspunkt 1051 und wird mit einer 'Speichermodifizierungs'-Prozedur 1053, die einen Speicherplatz in einer Karte modifiziert, fortgesetzt. Der 'Markiere-Abschnitt'- Prozeß 1050 versucht, den Kartenvektor 1011 als Teil der Schreibsperre in einer 'Kartenmodifizierungs'-Prozedur 1055 zu aktualisieren. Wenn der Kartenmerker in dem Kartenvektor 1011 Lesen-Schreiben ist, ermöglicht ein 'Speicherschutz'-Prozeß 1057, daß die Schreiboperation abgeschlossen wird - womit der Kartenmerker markiert wird. Nachfolgend wird der 'Markiere-Abschnitt'-Prozeß 1050 über einen 'Ende'-Endpunkt 1059 abgeschlossen. Wenn der Kartenmerker in dem Kartenvektor 1011 aber Nur-Lesen ist, erfaßt der 'Speicherschutz'-Prozeß 1057 die geschützte Schreiboperation und meldet einen Fehler. Die Fehlerverarbeitung beginnt bei einem 'Fehler'-Ausgangspunkt 1061 und wird mit einer 'Speicherfehler-Organisationsaufwand'-Prozedur 1063, die Prozeduren im Zusammenhang mit dem Fehlerorganisationsaufwand ausführt, fortgesetzt. Darauf ändert eine 'Gib-Schreiboperation-frei'- Prozedur 1065 den Schutz für denjenigen Teil des Kartenvektors 1011, der den Zielkartenmerker enthält, von Nur- Lesen auf Lesen-Schreiben. Nachfolgend schließt eine Schließe-Schreiboperation-ab'-Prozedur 1067 die vorausgehende fehlerhafte Schreiboperation in den Kartenmerker ab. Daraufhin aktualisiert eine 'Aktualisiere-Abschnittsstruktur'-Prozedur 1069 das 'Abschnitts-R/W-Status'-Feld 1031 zur Angabe, daß die Abschnittstruktur 1030 unrein ist und während der nächsten Reinigungsoperation abgetastet werden muß. Schließlich wird die fehlerhafte Verarbeitung über einen 'Rücksprung'-Endpunkt 1071 abgeschlossen, während der 'Markiere-Abschnitt'-Prozeß 1050 über den 'Ende'-Endpunkt 1059 abgeschlossen wird.
- Fig. 10d zeigt einen mit dem allgemeinen Bezugszeichen 1080 bezeichneten 'Sammle-Abschnitt'-Prozeß. Der 'Sammle- Abschnitt'-Prozeß 1080 beginnt mit einem 'Start'-Ausgangspunkt 1081 und wird mit einer Iterationsprozedur 1083 fortgesetzt. Die Iterationsprozedur 1083 iteriert über sämtliche Abschnitte in dem Abschnittsvektor 1013. Wenn der letzte Abschnitt in dem Abschnittsvektor 1013 verarbeitet ist, wird der 'Sammle-Abschnitt'-Prozeß 1080 über einen 'Ende'-Endpunkt 1085 abgeschlossen. Während jeder Iteration der Iterationsprozedur 1083 bestimmt eine Entscheidungsprozedur 1087, ob das 'Abschnitts-R/W-Status'-Feld 1031 statt Nur-Lesen Lesen-Schreiben ist. Wenn das 'Abschnitts-R/W-Status'-Feld 1031 nicht Lesen-Schreiben ist, schreitet der 'Sammle-Abschnitt'-Prozeß 1080 zur nächsten Iteration der Iterationsprozedur 1083 fort, wobei er jeden Kartenmerker in dem Teil des Kartenvektors 1011 wegläßt. Wenn aber das 'Abschnitts-R/W-Status'-Feld 1031 Lesen-Schreiben ist, wird der Prozeß mit einer Iterationsprozedur 1089 fortgesetzt, die über jeden Kartenmerker in dem durch den iterierten Abschnitt gesteuerten Teil des Kartenvektors 1011 iteriert. Jede Karte wird durch eine 'Verarbeite-Karte'-Prozedur 1091 verarbeitet, um die reinigungsbezogene Operation an dieser iterierten Karte auszuführen. Wenn irgendein Kartenmerker in dem Abschnitt markiert ist, wird während dieser Verarbeitung ein Statusbit gesetzt. Wenn sämtliche Karten in dem iterierten Abschnitt bearbeitet sind, wird der Prozeß mit einer Entscheidungsprozedur 1093, die bestimmt, ob irgendein Kartenmerker in dem iterierten Abschnitt markiert wurde, fortgesetzt. Wenn irgendein Kartenmerker markiert wurde, wird der 'Sammle-Abschnitt'- Prozeß 1080 mit einer 'Setze-Zeitgeber-zurück'-Prozedur 1095, die das 'Herunterzähl-Zeitgeber'-Feld 1039 zurücksetzt und die Zeit der momentanen Reinigungsoperation in dem 'Zuletzt-modifiziert-Zeit'-Feld 1033 der Abschnittsstruktur 1030 anordnet, fortgesetzt. Nachfolgend wird der 'Sammle-Abschnitt'-Prozeß 1080 mit der Iterationsprozedur 1083 zum Verarbeiten des nächsten Abschnitts fortgesetzt. Wenn aber in der Entscheidungsprozedur 1093 kein Kartenmerker in dem iterierten Abschnitt markiert wurde, wird der 'Sammle-Abschnitt'-Prozeß 1080 mit einer 'Dekrementiere-Zeitgeber'-Prozedur 1097, die den in dem 'Herunterzähl-Zeitgeber'-Feld 1039 gespeicherten Wert dekrementiert, fortgesetzt. Nachfolgend wird der Wert des 'Herunterzähl-Zeitgeber'-Feldes 1039 in einer 'Zeitgeberüberprüfungsentscheidung'-Prozedur 1098 auf null getestet. Wenn das 'Herunterzähl-Zeitgeber'-Feld 1039 nicht null ist, wird der 'Sammle-Abschnitt'-Prozeß 1080 mit der Iterationsprozedur 1083 zum Verarbeiten des nächsten Abschnitts fortgesetzt. Wenn das 'Herunterzähl-Zeitgeber'-Feld 1039 null ist, setzt eine 'Setze-Abschnitt-auf- Nur-Lesen'-Prozedur 1099 die Speicherschutzhardware auf Nur-Lesen, so daß versuchte Schreiboperationen auf diesen Abschnitt des Kartenvektors 1011 einen Fehler verursachen. Außerdem setzt die 'Setze-Abschnitt-auf-Nur-Lesen'- Prozedur 1099 das 'Abschnitts-R/W-Status'-Feld 1031 der momentanen Abschnittsstruktur auf Nur-Lesen. Nachfolgend wird der 'Sammle-Abschnitt'-Prozeß 1080 mit der Iterationsprozedur 1083 zum Verarbeiten der, nächsten Abschnittsstruktur fortgesetzt.
- Der Fachmann auf dem Gebiet versteht, daß die zuvor beschriebene Erfindung ein Verfahren, ein System, eine Vorrichtung und ein Programmierprodukt lehrt, die eine Datenstruktur schaffen, die sowohl einfach auf Zeigerwerte abgetastet werden kann als auch Aspekte instanziierter Objekte in einer OOP-Umgebung vereinfacht.
Claims (12)
1. Computergesteuertes Speicherbereinigungsverfahren
zum Lokalisieren eines Zeigerwertes in einer
Datenstruktur, die eine Header-Struktur (301) umfaßt,
gekennzeichnet durch die folgenden Schritte:
(a) Konstruieren der Datenstruktur (300), in der
ein Zeiger-Speicherbereich (303) von einem Datenwert-
Speicherbereich (305) durch die Header-Struktur (301)
getrennt ist, wobei der Zeiger-Speicherbereich (303) eine
Zeigervariable (325) enthält, die den Zeigerwert (325)
enthält, wobei die Header-Struktur (301) einen vom
Zeigerwert (325) unterscheidbaren Header-Wert enthält und an
den Zeiger-Speicherbereich (303) angrenzt;
(b) Abtasten (350) des Zeiger-Speicherbereichs
(303), um den Zeigerwert (325) zu lokalisieren, und
Erfassen des Header-Wertes (301); und
(c) Vorwärtsbewegen (367) am Datenwertspeicher
(305) und am Rest der Objekt-Header-Struktur (301)
vorbei, wenn der Header-Wert (301) erfaßt wird.
2. Computergesteuertes Speicherbereinigungsverfahren
nach Anspruch 1, bei dem die Datenstruktur (300) eine
erste instanziierte Objekt-Datenstruktur ist, die
Zeigervariable eine Zeigerinstanz-Variable ist und die Header-
Struktur (305) eine Objekt-Header-Struktur ist.
3. Computergesteuertes Speicherbereinigungsverfahren
nach Anspruch 2, bei dem der Objekt-Header-Struktur (301)
ein Größenfeld zugeordnet ist, das die Größe des
Datenwert-Speicherbereichs enthält, wobei der ersten
instanziierten Objekt-Datenstruktur in einem ununterbrochen
adressierbaren Speicherbereich eine zweite instanziierte
Objekt-Datenstruktur folgt, und der Schritt (c) die
folgenden Schritte umfaßt:
(c1) Bestimmen eines Vorwärtsbewegungswertes aus
dem Größenfeld; und
(c2) Vorwärtsbewegen (367) bis zu der zweiten
instanziierten Objekt-Datenstruktur unter Verwendung des
Vorwärtsbewegungswertes.
4. Computergesteuertes Speicherbereinigungsverfahren
nach Anspruch 2, bei dem der Zeigerwert auf eine zweite
instanziierte Objekt-Datenstruktur zeigt und der Schritt
(c) das Verfolgen des Zeigerwertes bis zu der zweiten
instanziierten Objekt-Datenstruktur umfaßt.
5. Computergesteuertes Speicherbereinigungsverfahren
nach Anspruch 2, bei dem die erste instanziierte Objekt-
Datenstruktur aus einer Basisklasse abgeleitet wird, die
eine Instanzvariable in der ersten instanziierten Objekt-
Datenstruktur definiert, die von der Objekt-Header-
Struktur versetzt ist, und bei dem eine zweite
instanziierte Objekt-Datenstruktur, die auf einer Unterklasse der
Basisklasse basiert, ebenfalls die Instanzvariable in der
zweiten instanziierten Objekt-Datenstruktur definiert,
die ebenfalls versetzt ist.
6. Instanziierte
Speicherbereinigungs-Objekt-Datenstruktur (301), die in einem Verfahren nach Anspruch 1
verwendet wird, gekennzeichnet durch:
einen Zeiger-Speicherbereich (303), der eine
Zeiger-Instanzvariable (325) zum Speichern eines
Zeigerwertes enthält;
einen Datenwert-Speicherbereich (305) zum
Speichern eines Nichtzeigerwertes (323); und
eine Objekt-Header-Struktur (301), die einen vom
Zeigerwert unterscheidbaren Header-Wert enthält und an
den Zeiger-Speicherbereich (303) angrenzt, wobei die
Objekt-Header-Struktur (301) den Zeiger-Speicherbereich
und den Datenwert-Speicherbereich trennt.
7. Vorrichtung mit einer Zentraleinheit (CPU) (203)
und der Speicherbereinigungs-Objektdatenstruktur (300)
nach Anspruch 6, die mit der CPU (203) gekoppelt ist und
der Lokalisierung eines Zeigerwertes in der Datenstruktur
während der Speicherbereinigung dient, wobei die
Vorrichtung umfaßt:
Abtasteinrichtungen (350), die so beschaffen
sind, daß sie den Zeiger-Speicherbereich (303) abtasten,
um den Zeigerwert zu lokalisieren, und Header-
Erfassungseinrichtungen enthalten, die so beschaffen
sind, daß sie den Header-Wert während der Operation des
Abtastmechanismus erfassen; und
Vorwärtsbewegungseinrichtungen (367), die so
beschaffen sind, daß sie sich in Abhängigkeit von den
Header-Erfassungseinrichtungen am
Datenwert-Speicherbereich und an der restlichen Objekt-Header-Struktur
(301) vorbei vorwärtsbewegen.
8. Vorrichtung nach Anspruch 7, bei der die
Speicherbereinigungs-Objekt-Datenstruktur eine erste
instanziierte Objekt-Datenstruktur ist, die Zeigervariable eine
Zeigerinstanz-Variable ist und die Header-Struktur eine
Objekt-Header-Struktur ist.
9. Vorrichtung nach Anspruch 8, in der der Objekt-
Header-Struktur ein Größenfeld zugeordnet ist, das die
Größe des Datenwert-Speicherbereichs enthält, der ersten
instanziierten Objekt-Datenstruktur in einem
ununterbrochen adressierbaren Speicherbereich eine zweite
instanziierte Objekt-Datenstruktur folgt und die
Vorwärtsbewegungseinrichtungen umfassen:
eine Bestimmungseinrichtung, die so beschaffen
ist, daß sie aus dem Größenfeld einen
Vorwärtsbewegungswert bestimmt; und
eine Vorwärtsvorbeibewegungs-Objekteinrichtung
(367), die so beschaffen ist, daß sie sich unter
Verwendung des Vorwärtsbewegungswertes zu der zweiten
instanziierten Objekt-Datenstruktur vorwärtsbewegt.
10. Vorrichtung nach Anspruch 8 oder Anspruch 9, in
der der Zeigerwert auf eine zweite instanziierte Objekt-
Datenstruktur zeigt und die Vorwärtsbewegungseinrichtung
eine Zeiger-Verfolgungseinrichtung umfaßt, die so
beschaffen ist, daß sie dem Zeigerwert zur zweiten
instanziierten Objekt-Datenstruktur folgt.
11. Vorrichtung nach einem der Ansprüche 8 bis 10, in
der die erste instanziierte Objekt-Datenstruktur aus
einer Basisklasse abgeleitet wird, die eine
Instanzvariable in der ersten instanziierten Objekt-Datenstruktur
definiert und von der Objekt-Header-Btruktur versetzt
ist, und in der eine zweite instanziierte
Objektdatenstruktur, die auf einer Unterklasse der Basisklasse
basiert, auch die Instanzvariable in der zweiten
instanziierten Objekt-Datenstruktur definiert, die ebenfalls
versetzt ist.
12. Computerprogramm, das dann, wenn es auf einem
Computer läuft, insbesondere so beschaffen ist, daß es
sämtliche Verfahrensschritte nach einem der Ansprüche 1
bis 5 ausführt.
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
US08/842,195 US5900001A (en) | 1997-04-23 | 1997-04-23 | Method and apparatus for optimizing exact garbage collection using a bifurcated data structure |
Publications (2)
Publication Number | Publication Date |
---|---|
DE69801186D1 DE69801186D1 (de) | 2001-08-30 |
DE69801186T2 true DE69801186T2 (de) | 2002-05-02 |
Family
ID=25286747
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
DE69801186T Expired - Fee Related DE69801186T2 (de) | 1997-04-23 | 1998-04-20 | Verfahren und Vorrichtung zum Auffinden von Objekt-Zeigern, für die Erkennung/Sammlung von nicht-referenzierten Daten-Objekten |
Country Status (4)
Country | Link |
---|---|
US (1) | US5900001A (de) |
EP (1) | EP0874318B1 (de) |
JP (1) | JPH10301836A (de) |
DE (1) | DE69801186T2 (de) |
Families Citing this family (95)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US6105040A (en) * | 1997-06-30 | 2000-08-15 | Sun Microsystems, Inc. | Method and apparatus for managing stored objects |
US6560773B1 (en) * | 1997-12-12 | 2003-05-06 | International Business Machines Corporation | Method and system for memory leak detection in an object-oriented environment during real-time trace processing |
US6295640B1 (en) * | 1998-05-08 | 2001-09-25 | Apple Computer, Inc. | Method and apparatus for distinguishing reference values from non-reference values in a runtime environment |
US6141738A (en) * | 1998-07-08 | 2000-10-31 | Nortel Networks Corporation | Address translation method and system having a forwarding table data structure |
US6327701B2 (en) * | 1998-09-15 | 2001-12-04 | Sun Microsystems, Inc. | Method and apparatus for finding bugs related to garbage collection in a virtual machine |
US6317756B1 (en) * | 1998-10-07 | 2001-11-13 | International Business Machines Corporation | On-the-fly garbage collector |
US6279148B1 (en) * | 1998-10-13 | 2001-08-21 | Sun Microsystems, Inc. | Method and apparatus for supporting efficient programming in dynamic pointer-safe languages |
US6842853B1 (en) * | 1999-01-13 | 2005-01-11 | Sun Microsystems, Inc. | Thread suspension system and method |
US6249793B1 (en) | 1999-06-10 | 2001-06-19 | Sun Microsystems, Inc. | Mostly concurrent compaction in a garbage collection system |
US6363403B1 (en) | 1999-06-30 | 2002-03-26 | Lucent Technologies Inc. | Garbage collection in object oriented databases using transactional cyclic reference counting |
US7150005B2 (en) * | 1999-07-02 | 2006-12-12 | Beryl Technical Assays, Llc | Method and system for global constant management for memory |
US6968549B1 (en) * | 1999-07-02 | 2005-11-22 | Beryl Technical Assays Llc | Method and system for dynamically loading data structures into memory with global constant pool |
US6381738B1 (en) * | 1999-07-16 | 2002-04-30 | International Business Machines Corporation | Method for optimizing creation and destruction of objects in computer programs |
US6424977B1 (en) | 1999-08-19 | 2002-07-23 | Sun Microsystems, Inc. | Train-algorithm-based garbage collector employing reduced oversized-object threshold |
US6434576B1 (en) | 1999-08-19 | 2002-08-13 | Sun Microsystems, Inc. | Popular-object handling in a train-algorithm-based garbage collector |
US6434577B1 (en) | 1999-08-19 | 2002-08-13 | Sun Microsystems, Inc. | Scalable-remembered-set garbage collection |
US6415302B1 (en) | 1999-08-19 | 2002-07-02 | Sun Microsystems, Inc. | Train-algorithm-based garbage collector employing farthest-forward-car indicator |
US6449626B1 (en) | 1999-08-19 | 2002-09-10 | Sun Microsystems, Inc. | Reduced-cost remembered-set processing in a train-algorithm-based garbage collector |
US6185581B1 (en) * | 1999-08-19 | 2001-02-06 | Sun Microsystems, Inc. | Train-algorithm-based garbage collector employing fixed-size remembered sets |
US7096238B2 (en) | 1999-08-19 | 2006-08-22 | Sun Microsystems, Inc. | Dynamic feedback for determining collection-set size |
US6944637B2 (en) * | 2000-02-07 | 2005-09-13 | Esmertec Ag | Reduced size objects headers |
US20010031468A1 (en) * | 2000-02-08 | 2001-10-18 | Alex Chenchik | Analyte assays employing universal arrays |
US6529919B1 (en) | 2000-02-15 | 2003-03-04 | Sun Microsystems, Inc. | Incremental class unloading in a train-algorithm-based garbage collector |
US6658652B1 (en) * | 2000-06-08 | 2003-12-02 | International Business Machines Corporation | Method and system for shadow heap memory leak detection and other heap analysis in an object-oriented environment during real-time trace processing |
US6738875B1 (en) | 2000-07-31 | 2004-05-18 | Microsoft Corporation | Efficient write-watch mechanism useful for garbage collection in a computer system |
US7051056B2 (en) | 2000-09-13 | 2006-05-23 | Veritas Operating Corporation | Conservative garbage collectors that can be used with general memory allocators |
GB0027045D0 (en) * | 2000-11-06 | 2000-12-20 | Ibm | Computer system with heap reset |
US6879991B2 (en) * | 2000-12-11 | 2005-04-12 | International Business Machines Corporation | Synchronous collection of cyclic garbage in reference counting systems |
US6457023B1 (en) * | 2000-12-28 | 2002-09-24 | International Business Machines Corporation | Estimation of object lifetime using static analysis |
US6820183B2 (en) | 2001-01-05 | 2004-11-16 | International Business Machines Corporation | Methods, systems, and computer program products for memory pool management using variable size sub-pools |
US6654773B2 (en) | 2001-02-27 | 2003-11-25 | Tajea Corporation | Method of deterministic garbage collection |
US6598141B1 (en) | 2001-03-08 | 2003-07-22 | Microsoft Corporation | Manipulating interior pointers on a stack during garbage collection |
US7203756B2 (en) * | 2001-04-27 | 2007-04-10 | International Business Machines Corporation | Mechanism to cache references to Java RMI remote objects implementing the unreferenced interface |
US6804681B2 (en) * | 2001-05-08 | 2004-10-12 | Sun Microsystems, Inc. | Identifying and tracking object references in a java programming environment |
US7065747B2 (en) * | 2001-05-08 | 2006-06-20 | Sun Microsystems, Inc. | Identifying references to objects during bytecode verification |
US7107430B2 (en) * | 2001-06-19 | 2006-09-12 | Massachusetts Institute Of Technology | Mechanism to reduce the cost of forwarding pointer aliasing |
GB0115965D0 (en) * | 2001-06-29 | 2001-08-22 | Ibm | Computer system for detecting object updates |
US20030089764A1 (en) * | 2001-11-13 | 2003-05-15 | Payformance Corporation | Creating counterfeit-resistant self-authenticating documents using cryptographic and biometric techniques |
US6807551B2 (en) * | 2002-04-22 | 2004-10-19 | Sun Microsystems Inc. | Measuring maximum memory requirement of an application at any point through continuous use of garbage collector |
US6928460B2 (en) * | 2002-07-01 | 2005-08-09 | Sun Microsystems, Inc. | Method and apparatus for performing generational garbage collection in a segmented heap |
US7539713B2 (en) | 2002-11-05 | 2009-05-26 | Sun Microsystems, Inc. | Allocation of likely popular objects in the train algorithm |
US6999979B2 (en) * | 2002-11-05 | 2006-02-14 | Sun Microsystems, Inc. | Efficient encoding of references into a collection set |
US7035884B2 (en) * | 2002-11-05 | 2006-04-25 | Sun Microsystems, Inc. | Placement of allocation trains in the train algorithm |
US7188129B2 (en) | 2002-11-15 | 2007-03-06 | Sun Microsystems, Inc. | Merging trains in a collector based on the train algorithm |
US7209935B2 (en) * | 2002-11-27 | 2007-04-24 | Sun Microsystems, Inc. | Avoiding remembered-set maintenance overhead for memory segments known to be in a collection set |
US7069280B2 (en) | 2002-12-06 | 2006-06-27 | Sun Microsystems, Inc. | Collection-tick mechanism for a collector based on the train algorithm |
US7031990B2 (en) | 2002-12-06 | 2006-04-18 | Sun Microsystems, Inc. | Combining external and intragenerational reference-processing in a garbage collector based on the train algorithm |
US7143124B2 (en) | 2002-12-06 | 2006-11-28 | Sun Microsystems, Inc. | Detection of dead regions during incremental collection |
US7085790B2 (en) * | 2002-12-06 | 2006-08-01 | Sun Microsystems, Inc. | Advancing cars in trains managed by a collector based on the train algorithm |
US7024437B2 (en) * | 2002-12-06 | 2006-04-04 | Sun Microsystems, Inc. | Better placement of objects reachable from special objects during collection based on the train algorithm |
US7246141B2 (en) * | 2003-01-02 | 2007-07-17 | Sun Microsystems, Inc. | Method and apparatus for skewing a bi-directional object layout to improve cache performance |
US7146390B2 (en) | 2003-02-24 | 2006-12-05 | Sun Microsystems, Inc. | Staging the processing of remembered-set entries as part of collection based on the train algorithm |
US7069281B2 (en) | 2003-02-24 | 2006-06-27 | Sun Microsystems, Inc. | Efficient collocation of evacuated objects in a copying garbage collector using variably filled local allocation buffers |
US7096329B2 (en) * | 2003-02-27 | 2006-08-22 | Sun Microsystems, Inc. | Better placement of objects promoted into a generation managed by the train algorithm |
US7062519B2 (en) * | 2003-02-27 | 2006-06-13 | Sun Microsystems, Inc. | Incremental scanning of enormous objects to improve scheduling and pause-time behavior of garbage collection |
US7730449B2 (en) * | 2003-03-19 | 2010-06-01 | Toshiba Corporation | Auto reference counting pointer for C++ objects with ability to re-cast and lookup from a free pointer |
US20040186863A1 (en) * | 2003-03-21 | 2004-09-23 | Garthwaite Alexander T. | Elision of write barriers for stores whose values are in close proximity |
US7089272B1 (en) | 2003-06-18 | 2006-08-08 | Sun Microsystems, Inc. | Specializing write-barriers for objects in a garbage collected heap |
DE10329680A1 (de) * | 2003-07-01 | 2005-02-10 | Universität Stuttgart | Prozessorarchitektur für exakte Zeigeridentifizierung |
US7149762B1 (en) | 2003-08-20 | 2006-12-12 | Sun Microsystems, Inc. | Handling futile collections in the train algorithm through selective extension of the collection set |
KR100626368B1 (ko) * | 2003-08-25 | 2006-09-20 | 삼성전자주식회사 | 가비지 콜렉션 벤치마킹 방법 |
US7404182B1 (en) | 2003-10-03 | 2008-07-22 | Sun Microsystems, Inc. | Deferring and combining write barriers for a garbage-collected heap |
US7702663B2 (en) * | 2004-01-05 | 2010-04-20 | International Business Machines Corporation | Breaking read barrier to apply optimizations |
US8131955B2 (en) * | 2004-04-15 | 2012-03-06 | Microsoft Corporation | Ephemeral garbage collection using a tracking mechanism on a card table to determine marked bundles |
US7620943B1 (en) | 2004-06-30 | 2009-11-17 | Sun Microsystems, Inc. | Using class properties to segregate objects in a generation managed by the train algorithm |
US7676801B1 (en) | 2004-08-31 | 2010-03-09 | Sun Microsystems, Inc. | Scanning of evacuated objects in a generation managed by the train algorithm |
US7321909B1 (en) | 2004-12-23 | 2008-01-22 | Sun Microsystems, Inc. | Method and apparatus for forwarding references to objects concurrently with space-incremental garbage collection |
US7870170B2 (en) * | 2005-05-03 | 2011-01-11 | International Business Machines Corporation | Method and apparatus for determining leaks in a Java heap |
US7548940B2 (en) * | 2005-06-10 | 2009-06-16 | International Business Machines Corporation | Generational real-time garbage collection |
GB0512809D0 (en) * | 2005-06-23 | 2005-08-03 | Ibm | Arrangement and method for garbage collection in a computer system |
US7558804B1 (en) * | 2005-08-26 | 2009-07-07 | American Megatrends, Inc. | Method, apparatus, and computer-readable medium for space-efficient storage of variables in a non-volatile computer memory |
US7627621B2 (en) * | 2007-02-12 | 2009-12-01 | Sun Microsystems, Inc. | Method and system for minor garbage collection |
US7870171B2 (en) * | 2007-02-12 | 2011-01-11 | Oracle America, Inc. | Method and system for garbage collection in a multitasking environment |
US7890711B2 (en) * | 2007-04-18 | 2011-02-15 | Oracle America, Inc. | Methods, apparatus, and program products for improved finalization |
US8732442B2 (en) * | 2008-06-25 | 2014-05-20 | Oracle America, Inc. | Method and system for hardware-based security of object references |
US8577936B2 (en) * | 2010-11-29 | 2013-11-05 | International Business Machines Corporation | Fixup cache tool for object memory compaction in an information handling system |
US9378138B2 (en) * | 2011-06-29 | 2016-06-28 | International Business Machines Corporation | Conservative garbage collection and access protection |
US8726255B2 (en) | 2012-05-01 | 2014-05-13 | Concurix Corporation | Recompiling with generic to specific replacement |
US9417935B2 (en) | 2012-05-01 | 2016-08-16 | Microsoft Technology Licensing, Llc | Many-core process scheduling to maximize cache usage |
US8650538B2 (en) | 2012-05-01 | 2014-02-11 | Concurix Corporation | Meta garbage collection for functional code |
US8595743B2 (en) | 2012-05-01 | 2013-11-26 | Concurix Corporation | Network aware process scheduling |
US9230548B2 (en) * | 2012-06-06 | 2016-01-05 | Cypress Semiconductor Corporation | Hybrid hashing scheme for active HMMS |
US9047196B2 (en) | 2012-06-19 | 2015-06-02 | Concurix Corporation | Usage aware NUMA process scheduling |
US8700838B2 (en) | 2012-06-19 | 2014-04-15 | Concurix Corporation | Allocating heaps in NUMA systems |
US8793669B2 (en) | 2012-07-17 | 2014-07-29 | Concurix Corporation | Pattern extraction from executable code in message passing environments |
US8707326B2 (en) | 2012-07-17 | 2014-04-22 | Concurix Corporation | Pattern matching process scheduler in message passing environment |
US9575813B2 (en) | 2012-07-17 | 2017-02-21 | Microsoft Technology Licensing, Llc | Pattern matching process scheduler with upstream optimization |
US9043788B2 (en) | 2012-08-10 | 2015-05-26 | Concurix Corporation | Experiment manager for manycore systems |
US8688754B1 (en) | 2012-09-19 | 2014-04-01 | International Business Machines Corporation | Remembered set overhead reduction by deferred garbage collections of stable regions |
US8656134B2 (en) | 2012-11-08 | 2014-02-18 | Concurix Corporation | Optimized memory configuration deployed on executing code |
US8607018B2 (en) | 2012-11-08 | 2013-12-10 | Concurix Corporation | Memory usage configuration based on observations |
US8656135B2 (en) | 2012-11-08 | 2014-02-18 | Concurix Corporation | Optimized memory configuration deployed prior to execution |
US20130219372A1 (en) | 2013-03-15 | 2013-08-22 | Concurix Corporation | Runtime Settings Derived from Relationships Identified in Tracer Data |
US11429492B2 (en) * | 2018-04-27 | 2022-08-30 | EMC IP Holding Company LLC | Protecting and identifying virtual machines that have the same name in a multi-tenant distributed environment |
CN110543357B (zh) * | 2018-05-28 | 2023-01-13 | 华为云计算技术有限公司 | 管理应用程序对象的方法,相关装置及系统 |
Family Cites Families (23)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US4922414A (en) * | 1982-12-17 | 1990-05-01 | Symbolics Inc. | Symbolic language data processing system |
US4757438A (en) * | 1984-07-12 | 1988-07-12 | Texas Instruments Incorporated | Computer system enabling automatic memory management operations |
US4775932A (en) * | 1984-07-31 | 1988-10-04 | Texas Instruments Incorporated | Computer memory system with parallel garbage collection independent from an associated user processor |
US4920483A (en) * | 1985-11-15 | 1990-04-24 | Data General Corporation | A computer memory for accessing any word-sized group of contiguous bits |
US5222221A (en) * | 1986-06-17 | 1993-06-22 | Yeda Research And Development Co., Ltd. | Method and apparatus for implementing a concurrent logic program |
US4989134A (en) * | 1987-03-20 | 1991-01-29 | Hewlett-Packard Company | Method and apparatus for enhancing data storage efficiency |
US5136706A (en) * | 1987-04-30 | 1992-08-04 | Texas Instruments Incorporated | Adaptive memory management system for collection of garbage in a digital computer |
US4907151A (en) * | 1988-09-30 | 1990-03-06 | Digital Equipment Corporation | System and method for garbage collection with ambiguous roots |
US5088036A (en) * | 1989-01-17 | 1992-02-11 | Digital Equipment Corporation | Real time, concurrent garbage collection system and method |
US5321834A (en) * | 1989-11-28 | 1994-06-14 | Xerox Corporation | Method and system for reclaiming unreferenced computer memory space |
US5414826A (en) * | 1990-01-31 | 1995-05-09 | Hewlett-Packard Company | System and method for memory management in microcomputer |
JPH04506720A (ja) * | 1990-03-23 | 1992-11-19 | イーストマン・コダック・カンパニー | ディジタル・データ処理システムのための仮想メモリ管理及び割付け装置 |
US5193180A (en) * | 1991-06-21 | 1993-03-09 | Pure Software Inc. | System for modifying relocatable object code files to monitor accesses to dynamically allocated memory |
US5355483A (en) * | 1991-07-18 | 1994-10-11 | Next Computers | Asynchronous garbage collection |
US5392432A (en) * | 1991-08-27 | 1995-02-21 | At&T Corp. | Method for automatic system resource reclamation for object-oriented systems with real-time constraints |
US5218698A (en) * | 1991-11-22 | 1993-06-08 | Aerojet-General Corporation | Garbage collection system for a symbolic digital processor |
DE69327089T2 (de) * | 1992-07-24 | 2000-04-13 | Microsoft Corp., Redmond | Rechnerverfahren und system zur zuordnung und zur freigabe von speichern. |
US5560003A (en) * | 1992-12-21 | 1996-09-24 | Iowa State University Research Foundation, Inc. | System and hardware module for incremental real time garbage collection and memory management |
US5367685A (en) * | 1992-12-22 | 1994-11-22 | Firstperson, Inc. | Method and apparatus for resolving data references in generated code |
US5870764A (en) * | 1993-05-12 | 1999-02-09 | Apple Computer, Inc. | Method of managing a data structure for concurrent serial and parallel revision of a work |
US5408650A (en) * | 1993-06-29 | 1995-04-18 | Digital Equipment Corporation | Memory analysis system for dynamically displaying memory allocation and de-allocation events associated with an application program |
US5566321A (en) * | 1993-12-13 | 1996-10-15 | Cray Research, Inc. | Method of managing distributed memory within a massively parallel processing system |
US5687368A (en) * | 1994-07-22 | 1997-11-11 | Iowa State University Research Foundation, Inc. | CPU-controlled garbage-collecting memory module |
-
1997
- 1997-04-23 US US08/842,195 patent/US5900001A/en not_active Expired - Lifetime
-
1998
- 1998-04-20 DE DE69801186T patent/DE69801186T2/de not_active Expired - Fee Related
- 1998-04-20 EP EP98303014A patent/EP0874318B1/de not_active Expired - Lifetime
- 1998-04-22 JP JP10111782A patent/JPH10301836A/ja active Pending
Also Published As
Publication number | Publication date |
---|---|
EP0874318A2 (de) | 1998-10-28 |
EP0874318B1 (de) | 2001-07-25 |
US5900001A (en) | 1999-05-04 |
DE69801186D1 (de) | 2001-08-30 |
EP0874318A3 (de) | 1999-04-21 |
JPH10301836A (ja) | 1998-11-13 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
DE69801186T2 (de) | Verfahren und Vorrichtung zum Auffinden von Objekt-Zeigern, für die Erkennung/Sammlung von nicht-referenzierten Daten-Objekten | |
DE69800909T2 (de) | Verfahren und Vorrichtung zur Optimierung der präzisen Speicherbereinigung, bei der Programmschleifen mit Zeiger-Feldern verwendet werden | |
US5920876A (en) | Performing exact garbage collection using bitmaps that identify pointer values within objects | |
US6038572A (en) | Method and apparatus for localizing nodes in a garbage collected carded heap | |
US6115782A (en) | Method and apparatus for locating nodes in a carded heap using a card marking structure and a node advance value | |
US6049810A (en) | Method and apparatus for implementing a write barrier of a garbage collected heap | |
US5915255A (en) | Method and apparatus for referencing nodes using links | |
US5911144A (en) | Method and apparatus for optimizing the assignment of hash values to nodes residing in a garbage collected heap | |
DE69800686T2 (de) | Verfahren und Gerät für effizienten Operationen auf primären Typwerten ohne statisches Überladen | |
DE69404439T2 (de) | Programmodellierungssystem. | |
DE69400406T2 (de) | System und methode zur lokalisierung von geteilten bibliotheken | |
DE69902908T2 (de) | Verfahren und system zum implementieren von parametrisierten typen für kompatibilität mit bestehenden nicht-parametrisierten bibliotheken | |
DE69232761T2 (de) | Verfahren und vorrichtung zur aenderung von dynamische zuweisbaren objektcodedateien | |
DE69813160T2 (de) | Verfahren zur Objekt-Heap-Analyse zum Nachweis von Speicherverlusten und sonstigen Laufzeitinformationen | |
DE69427174T2 (de) | Dynamische Hochleistungsprogrammverknüpfung durch Cachespeicherung | |
US7308466B2 (en) | Memory reclamation method | |
DE60031370T2 (de) | Tokenbasierte verknüpfung | |
DE69926820T2 (de) | Verfahren, Anordnung und Rechnerprogrammprodukt zur Verriegelung von verbundenen Datenstrukturen in einer multithreading-fähigen Rechnerumgebung | |
DE69622305T2 (de) | Verfahren und Gerät für einen optimierenden Kompiler | |
US6381738B1 (en) | Method for optimizing creation and destruction of objects in computer programs | |
DE69738101T2 (de) | Verwaltung des Zugangs zu Objekten mit Hilfe von Referenzen mit drei Zuständen | |
DE19945992B4 (de) | Dynamisch optimierender Objektcode-Übersetzer zur Architekturemulation und dynamisches optimierendes Objektcode-Übersetzungsverfahren | |
DE69030425T2 (de) | Verfahren und Vorrichtung zur Kompilierung von Rechnerprogrammen mit Registerzuweisung zwischen Prozeduren | |
DE69909945T2 (de) | Verfahren und Anordnung zur Korrelation von Profildaten dynamisch erzeugt durch ein optimiertes ausführbares Programm mit Quellcodeanweisungen | |
DE19959758A1 (de) | Bestimmung der Art und der Genauigkeit von lokalen Variablen bei vorhandenen Subroutinen |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
8364 | No opposition during term of opposition | ||
8339 | Ceased/non-payment of the annual fee |