Frage

Der Heap -Speicher ist in Java Müll gesammelt.

Wird der Stapelmüll auch gesammelt?

Wie wird Stack Memory zurückgefordert?

Keine korrekte Lösung

Andere Tipps

Der Speicher auf dem Stapel enthält Methodenparameter und lokale Variablen (genauer gesagt: die Referenzen für Objekte und Variablen selbst für primitive Typen). Dies wird automatisch entfernt, wenn Sie die Methode verlassen. Wenn die Variablen Referenzen (auf Objekte) sind, befinden sich die Objekte selbst auf dem Haufen und werden vom Müllsammler behandelt.

Der Stapel ist also nicht auf die gleiche Weise mit Müll wie der Haufen, aber Stack ist eine Form der automatischen Speichermanagement in seiner eigenen (die vor der Müllsammlung).

EIN Eine detailliertere Antwort wird von Thomas Pornin gegeben, Schauen Sie sich das an, um weitere Details zu erhalten.

Der Stapel ist in Java nicht Müll gesammelt.

Der für eine bestimmte Methodenaufruf zugewiesene Stack wird befreit, wenn die Methode zurückgibt. Da dies eine sehr einfache LIFO -Struktur ist, ist keine Müllsammlung erforderlich.

Ein Ort, an dem die Stapel- und Müllsammlung interagieren, ist, dass Referenzen auf dem Stapel GC -Wurzeln sind (was bedeutet, dass sie die Wurzelreferenzen sind, aus denen die Erreichbarkeit entschieden wird).

Der Stapel könnte Müll gesammelt sein. In den meisten JVM -Implementierungen wird es jedoch als "Stapel" bearbeitet, was per Definition die Müllsammlung ausschließt.

Was wir den Stapel nennen, ist die Ansammlung von Methodenaktivierungskontexte: Für jede aufgerufene Methode ist dies die konzeptionelle Struktur, die die Methodenargumente, lokale Variablen, einen versteckten Zeiger auf den Kontext für die aufrufende Methode enthält, und einen Slot, um den Anweisungszeiger zu speichern. Der Aktivierungskontext ist als solches nicht von der Java -Sprache selbst zugänglich. Ein Kontext wird nutzlos, wenn die Methode ausgeht (mit a return oder wegen einer geworfenen Ausnahme). Wenn eine Methode A eine Methode B aufruft, ist es so garantiert, dass der Kontext für B garantiert ist, wenn eine Kontrolle wiederhergestellt wird. Dies impliziert, dass die Lebensdauer des Kontextes für B eine Unterbereichung der Lebensdauer des Kontextes für A ist. Daher kann Aktivierungskontexte (für einen bestimmten Thread) mit einem LIFO ("Last in, First Out") zugeteilt werden. In einfacheren Worten wird ein Stapel: Ein neuer Aktivierungskontext wird über den Kontextstapel gedrängt, und der Kontext oben wird der erste sein, der entsorgt wird.

In der Praxis sind die Aktivierungskontexte (auch genannt Stackrahmen) werden in Stapelreihenfolge in einem speziellen Bereich verkettet. Dieser Bereich wird beim Start des Fadens aus dem Betriebssystem erhalten, und das Betriebssystem erhält es zurück, wenn der Thread endet. Die Oberseite des Stapels wird von einem bestimmten Zeiger bezeichnet, der häufig in einem CPU -Register enthalten ist (dies hängt davon ab, ob das JVM Code interpretiert oder zusammenstellt). Der "Zeiger auf den Kontext des Anrufers" ist virtuell; Der Kontext des Anrufers befindet sich notwendigerweise direkt unten in Stapelreihenfolge. Der GC greift nicht ein: Der Bereich für den Stapel wird aus der Fadenaktivität selbst erstellt und synchron zurückgefordert. So funktioniert es auch in vielen Sprachen wie z. C, die überhaupt keinen GC haben.

Jetzt verhindert nichts, dass eine JVM -Implementierung etwas anderes tut, z. B. die Zuweisung von Aktivierungskontexten im Haufen und die Erfassung von GC. Dies geschieht normalerweise nicht in Java -virtuellen Maschinen, da die Stapelzuweisung schneller ist. Aber einige andere Sprachen müssen solche Dinge tun, vor allem diejenigen, die mit spielen Kontinuationen während immer noch ein gc (z. Planen und sein call-with-current-continuation Funktion), weil solche Spiele die oben erläuterte LIFO -Regel brechen.

Der Stapel Teil des Gedächtnisses funktioniert wie ein "Stapel". Ich weiß, es klingt schlecht, aber genau so funktioniert es. Daten werden nach oben hinzufügen (übereinander (pushed onto the stack) und wird automatisch von oben entfernt (popped off the stack) Wie Ihr Programm läuft. Es ist nicht Müll gesammelt - und es muss nicht sein, da dieser Speicher automatisch zurückgefordert wird, sobald die Daten vom Stapel gestoßen sind. Und wenn ich zurückgewiesen habe, meine ich nicht, dass es abgelehnt wird - es ist nur so, dass der Ort im Stapelspeicher, an dem die nächsten Daten gespeichert werden, verringert wird, da die Daten abgelöst werden.

Natürlich heißt das nicht, dass Sie sich überhaupt keine Sorgen um den Stack machen müssen. Wenn Sie eine rekursive Funktion oft ausführen, wird sie schließlich den gesamten Stapelraum verbrauchen. Das Gleiche gilt, wenn Sie viele Funktionen aufrufen, insbesondere wenn sie viele Parameter und/oder lokale Variablen haben.

Das Fazit ist jedoch, dass der Speicher des Stapels verwendet und zurückgefordert wird, wenn die Funktionen eingeben und den Umfang verlassen - automatisch. Am Ende der Ausführung Ihres Programms wäre der gesamte Stack -Speicher kostenlos und dann wieder an das Betriebssystem weitergeleitet.

Wenn Sie sich auf den auf dem Stapel verwendeten Speicher beziehen, ist er nicht Müll gesammelt.
Die virtuelle Java-Maschine verwendet explizite Bytecode-Anweisungen, um den Speicher auf dem Stapel zu reservieren und zu veröffentlichen. Diese Anweisungen werden vom Compiler generiert und die Lebensdauer von Primitiven wie int, boolean, doppelt und Objektreferenzen auf dem Stapel verwaltet.
Es gab Pläne, eine sogenannte Tail -Call -Optimierung zu implementieren, die einige Einträge aus dem Stapel entfernen würde, sobald bekannt ist, dass sie nicht mehr verwendet werden, aber ich kenne kein JVM, das dies bereits unterstützt.
Nein, es gibt keine Müllsammlung für den Stapel selbst, nur der Compiler generierte Push- und Pop -Anweisungen zur Verwaltung der Speicherverwendung.

Der Stapel selbst ist Teil eines Fadens. Der Stapel wird zugewiesen, wenn das Thread -Objekt erstellt und nach dem Abschluss des Fadens gesammelt wird und das Thread -Objekt nicht mehr referenziert wird.

Alle Objekte in Java werden auf dem Haufen zugewiesen. (Zumindest in Bezug auf die Spezifikation kann die tatsächliche Implementierung sie auf dem Stapel zuweisen, wenn sie sich transparent verhalten, als wären sie auf dem Haufen.)

Genau das Sammlerstück ist etwas subtil. Wenn sich die einzige Referenz auf ein Objekt in einem einzelnen Stapelrahmen befindet und gezeigt werden kann, dass Referenz nicht erneut verwendet wird, kann das Objekt gesammelt werden. Wenn das Objekt nur zum Lesen eines Feldes verwendet wird, kann dieses Feld gelesen und das Objekt früher als erwartet gesammelt werden.

Dies spielt normalerweise keine Rolle, es sei denn, Sie verwenden Finaliser (oder vermutlich vermutlich References). In diesem Fall sollten Sie vorsichtig sein und Schlösser/flüchtig verwenden, um a durchzusetzen happens-before Beziehung.

Wenn Fäden stoppen, wird normalerweise der gesamte Stapel behandelt.

Alles auf Stack wird von einem Müllsammler als globale Wurzeln behandelt. Also, ja, Sie können auf jeden Fall sagen, dass Stack "Müll gesammelt" ist.

Niemand, Daten werden aus Stack gedrückt und geplant, da Sie bei Methodenanrufen usw. innere Variablen in Methoden haben. Sie müssen sich nicht darum kümmern.

Nein. Der Stapel ist in Java nicht Müll gesammelt. Jeder Thread hat seinen eigenen Stack und enthält:

  1. Methodspezifische Werte (die kurzlebig sind) und
  2. Verweise auf die auf Heap erstellten Objekte und werden von der Methode bezeichnet

Diese Werte werden für jeden Methodenaufruf als Stapelrahmen in den Stapel gedrückt. Da der Stapel "Last-In First-Out" -Sreihenfolge folgt, wird am Ende jedes Methodenaufrufs jeder Stapelrahmen, das alle methodspezifischen Daten und die Verweise auf Objekte enthält, falls vorhanden.

Daher werden Daten in Stack automatisch gereinigt, sobald die Methode/das Programm aus dem Umfang ausgeht.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top