Was ist der Garbage Collector in Java?


103

Ich bin neu in Java und verwirrt über den Garbage Collector in Java. Was macht es eigentlich und wann kommt es in Aktion? Bitte beschreiben Sie einige der Eigenschaften des Garbage Collector in Java.


2
mögliches Duplikat der Garbage Collection
Ian Ringrose

10
Manchmal ist es besser, ein Kapitel in einem guten Buch zu lesen, um ein komplexes Thema von der Antwort auf eine Frage zu verstehen.
Ian Ringrose

4
@ Ian Es ist eine ähnliche Frage, aber kein Duplikat. Und diese Frage stinkt nach Hausaufgaben.
NullUserException

Antworten:


119

Der Garbage Collector ist ein Programm, das auf der Java Virtual Machine ausgeführt wird und Objekte entfernt, die nicht mehr von einer Java-Anwendung verwendet werden. Es ist eine Form der automatischen Speicherverwaltung .

Wenn eine typische Java-Anwendung ausgeführt wird, werden neue Objekte wie Strings und Files erstellt. Nach einer bestimmten Zeit werden diese Objekte jedoch nicht mehr verwendet. Schauen Sie sich zum Beispiel den folgenden Code an:

for (File f : files) {
    String s = f.getName();
}

Im obigen Code String swird das bei jeder Iteration der forSchleife erstellt. Dies bedeutet, dass in jeder Iteration ein wenig Speicher zugewiesen wird, um ein StringObjekt zu erstellen.

Wenn wir zum Code zurückkehren, können wir sehen, dass nach Ausführung einer einzelnen Iteration in der nächsten Iteration Stringdas in der vorherigen Iteration erstellte Objekt nicht mehr verwendet wird - dieses Objekt wird jetzt als "Müll" betrachtet.

Irgendwann werden wir viel Müll bekommen und Speicher wird für Objekte verwendet, die nicht mehr verwendet werden. Wenn dies so weitergeht, wird der Java Virtual Machine möglicherweise der Speicherplatz ausgehen, um neue Objekte zu erstellen.

Hier kommt der Müllsammler ins Spiel.

Der Garbage Collector sucht nach Objekten, die nicht mehr verwendet werden, und entfernt sie, wodurch der Speicher frei wird, sodass andere neue Objekte diesen Speicher verwenden können.

In Java wird die Speicherverwaltung vom Garbage Collector übernommen, in anderen Sprachen wie C muss die Speicherverwaltung jedoch mithilfe von Funktionen wie mallocund selbst durchgeführt werdenfree . Speicherverwaltung ist eines der Dinge, bei denen leicht Fehler gemacht werden können, die zu sogenannten Speicherlecks führen können - Stellen, an denen Speicher nicht zurückgefordert wird, wenn sie nicht mehr verwendet werden.

Automatische Speicherverwaltungsschemata wie die Speicherbereinigung sorgen dafür, dass sich der Programmierer nicht so sehr um Speicherverwaltungsprobleme kümmern muss, sodass er sich mehr auf die Entwicklung der Anwendungen konzentrieren kann, die er entwickeln muss.


Wäre es wahr zu sagen, dass eine Java-Anwendung, die auf einem Computer ausgeführt wird, zwei Funktionen zur Speicherbereinigung hat? Eins mit der Java Virtual Machine. Und dann eine auf dem Computer, auf dem Windows ausgeführt wird? (Oder irgendein anderes Betriebssystem)
Lealo

Nein, normalerweise werden Java-Anwendungen nur ausgeführt, wenn JRE vorhanden ist. Daher ist nur die Garbage Collection-Funktionalität von JVM erforderlich! @Lealo
Am_I_Helpful

18

Es gibt Speicher frei, der Objekten zugewiesen ist, die nicht mehr vom Programm verwendet werden - daher der Name "Garbage". Beispielsweise:

public static Object otherMethod(Object obj) {
    return new Object();
}

public static void main(String[] args) {
    Object myObj = new Object();
    myObj = otherMethod(myObj);
    // ... more code ...  
}

Ich weiß, dass dies extrem erfunden ist, aber hier, nachdem Sie otherMethod()das Original aufgerufen haben Object, wird es unerreichbar gemacht - und das ist "Müll", der Müll sammelt.

In Java wird der GC automatisch ausgeführt, Sie können ihn jedoch auch explizit mit aufrufen System.gc()und versuchen, eine größere Garbage Collection zu erzwingen. Wie Pascal Thivent betont, sollten Sie dies wirklich nicht tun müssen, und es könnte mehr schaden als nützen (siehe diese Frage ).

Weitere Informationen finden Sie im Wikipedia-Eintrag zu Garbage Collection und Tuning Garbage Collection (von Oracle).


1
AFAIK erzwingt System.gc()keine GC-Ausführung.
Itay Karo

1
+1 für das gute Codebeispiel. Beachten Sie, dass es durchaus gültig ist, dass der GC zerstört wird, myObjbevor der Aufruf otherMethoderfolgt, da er myObjzu diesem Zeitpunkt nicht mehr verfügbar ist.
Billy ONeal

@Italien Ich glaube, das ist implementierungsspezifisch.
NullUserException

2
Ich glaube, man sollte nicht anrufen System.gc(), der springende Punkt bei einem GC ist, dass man das nicht tun muss.
Pascal Thivent

Bei der Escape-Analyse ( en.wikipedia.org/wiki/Escape_analysis ) ist es möglich, dass die JVM das Objekt in diesem Beispiel nicht einmal an erster Stelle zuweist. Die gesamte Objekterstellung kann (theoretisch) wegoptimiert werden. Implementierung natürlich abhängig.
Mikera

15

Ein Objekt kann für die Garbage Collection oder GC verwendet werden, wenn es nicht über Live-Threads oder statische Verweise erreichbar ist.

Mit anderen Worten, Sie können sagen, dass ein Objekt für die Speicherbereinigung in Frage kommt, wenn alle Referenzen null sind. Zyklische Abhängigkeiten werden nicht als Referenz gezählt. Wenn also Objekt A einen Verweis auf Objekt B und Objekt B einen Verweis auf Objekt A hat und keine andere Live-Referenz vorhanden ist, können sowohl Objekt A als auch B die Garbage Collection durchführen.


Heap-Generationen für die Garbage Collection -

Java-Objekte werden in Java erstellt Heapund Heapzur Speicherbereinigung in Java in drei Teile oder Generationen unterteilt. Diese werden als Young (New) Generation, Tenured (Old) Generation und Perm Area des Heaps bezeichnet.

Java heap space Die neue Generation ist weiter in drei Teile unterteilt, die als Eden-Raum, Survivor 1 und Survivor 2-Raum bekannt sind. Wenn ein Objekt, das zum ersten Mal auf einem Haufen erstellt wurde, in einer neuen Generation im Eden-Raum erstellt wird und nach der anschließenden kleinen Speicherbereinigung, wenn ein Objekt überlebt, wird es zu Überlebender 1 und dann zu Überlebender 2 verschoben, bevor die große Speicherbereinigung dieses Objekt zur alten oder dauerhaften Generation verschiebt .

Im Perm-Bereich von Java Heap speichert JVM Metadaten zu Klassen und Methoden, zum String-Pool und zu Details auf Klassenebene.

Heap-Generationen für die Garbage Collection

Weitere Informationen finden Sie hier: Garbage Collection


Sie können JVM nicht zwingen, Garbage Collection auszuführen, obwohl Sie eine Anforderung mithilfe der Methode System.gc()oder stellen können Runtime.gc().

In java.lang.System

public static void gc() {
    Runtime.getRuntime().gc();  
}

In java.lang.Runtime

public native void gc();  // note native  method

Mark and Sweep-Algorithmus -

Dies ist einer der beliebtesten Algorithmen, die von der Garbage Collection verwendet werden. Jeder Garbage Collection-Algorithmus muss zwei grundlegende Operationen ausführen. Erstens sollte es in der Lage sein, alle nicht erreichbaren Objekte zu erkennen, und zweitens muss es den von den Garbage-Objekten verwendeten Heap-Speicherplatz zurückfordern und den Speicherplatz dem Programm wieder zur Verfügung stellen.

Die obigen Operationen werden vom Markierungs- und Sweep-Algorithmus in zwei Phasen ausgeführt:

  1. Phase markieren
  2. Sweep-Phase

Lesen Sie hier für weitere Details - Mark and Sweep-Algorithmus


6

Garbage Collector impliziert, dass Objekte, die vom Programm nicht mehr benötigt werden, "Garbage" sind und weggeworfen werden können.


6

Garbage Collector ist Teil von JRE, das sicherstellt, dass Objekte, auf die nicht verwiesen wird, aus dem Speicher freigegeben werden.
Es wird normalerweise ausgeführt, wenn der App der Speicher ausgeht. AFAIK enthält ein Diagramm, das die Verknüpfungen zwischen den Objekten darstellt, und isolierte Objekte können freigegeben werden.
Um die Leistung zu sparen, werden die aktuellen Objekte, die in Generationen gruppiert sind, jedes Mal, wenn GC ein Objekt scannt und feststellt, dass es immer noch referenziert wird, um 1 erhöht (auf einen maximalen Maximalwert, glaube ich 3 oder 4), und die neue Generation wird zuerst gescannt (Je kürzer das Objekt im Speicher ist, desto wahrscheinlicher wird es nicht mehr benötigt.) Daher werden nicht alle Objekte bei jedem GC-Lauf gescannt.
Lesen Sie dies für weitere Informationen.


@quantumSoup bist du in dieser Hinsicht besitzergreifend? Ich glaube, eine Art Müllabfuhr (eine teurere) findet nur statt, wenn sich der Haufen füllt.
Pablo Fernandez

2
@quantumSoup - das hängt von der GC-Implementierung der JRE ab. In vielen Fällen läuft der GC nicht ständig. Stattdessen wird es ausgeführt, wenn Ihre App kein Objekt zuordnen kann, weil der Heap voll ist. Aktuelle HotSpot-JVMs enthalten zwar einen parallelen GC, sind jedoch standardmäßig nicht aktiviert.
Stephen C

Diese Antwort konzentriert sich zu sehr auf den Mechanismus. Die Frage war "Was ist der Müllsammler", nicht "Wie funktioniert der Müllsammler"
Billy ONeal

@quantum: neutralisierte deine -1, weil: Lernen, das heißt, wofür diese Seite ist, richtig? Um zu lernen, müssen Sie Fehler machen. Durch die Bestrafung von Fehlern lernen die Menschen nicht. Ich hoffe, Sie können diesem Punkt zustimmen. Und vielleicht hast du hier einen Fehler gemacht.
Erikbwork

1
@erikb: Nach dieser Logik würde es niemals Downvotes geben. Und Abstimmungen sind notwendig, um relativ schlechte Antworten auszusortieren. Das OP ist offensichtlich ein Anfänger, und das spezifische Innenleben des GC ist für die gestellte Frage einfach nicht wichtig. Da diese Antwort die gestellte Frage nicht beantwortet (sie beantwortet eine andere), sind Abstimmungen vollkommen gerechtfertigt.
Billy ONeal

3

Mit dem Garbage Collector kann Ihr Computer einen Computer mit unendlichem Speicher simulieren. Der Rest ist nur Mechanismus.

Dazu wird erkannt, wann über Ihren Code nicht mehr auf Speicherblöcke zugegriffen werden kann, und diese Blöcke werden an den freien Speicher zurückgegeben.

EDIT: Ja, der Link ist für C #, aber C # und Java sind in dieser Hinsicht identisch.


Es gibt tatsächlich eine Frage zu SO über den Unterschied zwischen Java und C # 's GC: stackoverflow.com/questions/492703/c-vs-java-garbage-collector
NullUserException

3

Viele Leute denken, dass die Müllabfuhr tote Gegenstände sammelt und wegwirft.
In Wirklichkeit macht die Java-Garbage Collection das Gegenteil! Lebende Objekte werden verfolgt und alles andere als Müll bezeichnet.

Wenn ein Objekt nicht mehr verwendet wird, gewinnt der Garbage Collector den zugrunde liegenden Speicher zurück und verwendet ihn für die zukünftige Objektzuweisung. Dies bedeutet, dass keine explizite Löschung erfolgt und kein Speicher an das Betriebssystem zurückgegeben wird. Um festzustellen, welche Objekte nicht mehr verwendet werden, führt die JVM zeitweise einen sehr treffend als Mark-and-Sweep-Algorithmus bezeichneten Algorithmus aus.

Weitere Informationen finden Sie hier: http://javabook.compuware.com/content/memory/how-garbage-collection-works.aspx


1

Um es so einfach auszudrücken, dass selbst ein Nicht-Programmierer verstehen kann, wenn ein Programm Daten verarbeitet, erstellt es Zwischendaten und Speicherplatz (Variablen, Arrays, bestimmte Objektmetadaten usw.) für diese Daten.

Wenn auf diese Objekte funktionsübergreifend oder über eine bestimmte Größe zugegriffen wird, werden sie von einem zentralen Heap aus zugewiesen. Wenn sie dann nicht mehr benötigt werden, müssen sie gereinigt werden.

Es gibt einige sehr gute Artikel online darüber, wie dies funktioniert, daher werde ich nur die sehr grundlegende Definition behandeln.

Der GC ist im Grunde die Funktion, die diese Bereinigung durchführt. Dazu werden Tabelleneinträge gelöscht, auf die von keinen aktiven Objekten verwiesen wird, und die Objekte werden effektiv gelöscht. Anschließend wird der Speicher kopiert und komprimiert. Es ist etwas komplizierter als das, aber Sie bekommen die Idee.

Das große Problem ist, dass einige Teile dieses Prozesses häufig erfordern, dass die gesamte Java-VM vorübergehend gestoppt wird, um stattfinden zu können, und dass dieser gesamte Prozess sehr prozessor- und speicherbandbreitenintensiv ist. Die verschiedenen Optionen ab GCs und die Optimierungsoptionen für jede einzelne sind so konzipiert, dass diese verschiedenen Probleme mit dem gesamten GC-Prozess in Einklang gebracht werden.


0

Die Garbage Collection in Java (und auch in anderen Sprachen / Plattformen) ist eine Möglichkeit für die Java-Laufzeitumgebung (JRE), den Speicher von Java-Objekten wiederzuverwenden, die nicht mehr benötigt werden. Vereinfacht gesagt, fragt das JRE beim ersten Start das Betriebssystem (O / S) nach einer bestimmten Speichermenge. Während die JRE Ihre Anwendung (en) ausführt, verwendet sie diesen Speicher. Wenn Ihre Anwendung diesen Speicher verwendet, kommt der "Garbage Collector" der JRE und fordert diesen Speicher zur Verwendung durch verschiedene Teile Ihrer vorhandenen Anwendung (en) zurück. Der "Garbage Collector" der JRE ist eine Hintergrundaufgabe, die immer ausgeführt wird und versucht, Zeiten auszuwählen, in denen das System inaktiv ist, um seine Garbage Runs fortzusetzen.

Eine echte Analogie wären die Müllmänner, die zu Ihnen nach Hause kommen und Ihren recycelbaren Müll abholen ... schließlich wird er von Ihnen und / oder anderen Menschen auf andere Weise wiederverwendet.


0

Garbage Collector kann als Referenzzähler-Manager angesehen werden. Wenn ein Objekt erstellt und seine Referenz in einer Variablen gespeichert wird, wird seine Referenzanzahl um eins erhöht. im Verlauf der Ausführung, wenn dieser Variablen NULL zugewiesen wird. Der Referenzzähler für dieses Objekt wird dekrementiert. Der aktuelle Referenzzähler für das Objekt ist also 0. Wenn der Garbage Collector ausgeführt wird, sucht er nach Objekten mit dem Referenzzähler 0. Er gibt die ihm zugewiesenen Ressourcen frei.

Der Garbage Collector-Aufruf wird durch Garbage Collection-Richtlinien gesteuert.

Hier können Sie einige Daten abrufen. http://www.oracle.com/technetwork/java/gc-tuning-5-138395.html


1
Referenzzählung ist eine schlechte Möglichkeit, GC zu implementieren. Ich glaube nicht, dass eine größere JVM-Implementierung dies nutzt.
NullUserException

0

Garbage Collector ist eine Komponente von jvm.

Es wird verwendet, um Müll zu sammeln, wenn die CPU frei wird.

Hier bedeutet Müll nicht verwendete Objekte, die im Hintergrund des Hauptprogramms ausgeführt werden

um den Status des Hauptprogramms zu überwachen.


0

Bei der automatischen Speicherbereinigung wird der Heapspeicher überprüft, welche Objekte verwendet werden und welche nicht, und die nicht verwendeten Objekte werden gelöscht. Ein verwendetes Objekt oder ein referenziertes Objekt bedeutet, dass ein Teil Ihres Programms weiterhin einen Zeiger auf dieses Objekt verwaltet. Ein nicht verwendetes Objekt oder nicht referenziertes Objekt wird von keinem Teil Ihres Programms mehr referenziert. So kann der von einem nicht referenzierten Objekt verwendete Speicher zurückgefordert werden.

In einer Programmiersprache wie C ist das Zuweisen und Freigeben von Speicher ein manueller Vorgang. In Java wird der Prozess der Freigabe des Speichers automatisch vom Garbage Collector ausgeführt. Bitte überprüfen Sie den Link zum besseren Verständnis. http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html


0

Die Speicherbereinigung bezieht sich auf den Vorgang des automatischen Freigebens von Speicher auf dem Heap durch Löschen von Objekten, die in Ihrem Programm nicht mehr erreichbar sind. Der Heap ist ein Speicher, der als freier Speicher bezeichnet wird und einen großen Pool nicht verwendeten Speichers darstellt, der Ihrer Java-Anwendung zugewiesen ist.


1
Verwenden Sie die Anführungszeichenformatierung nicht für Text, der nicht in Anführungszeichen steht. Wenn er in Anführungszeichen steht, müssen Sie die Quelle angeben.
Marquis von Lorne

0

Die Grundprinzipien der Speicherbereinigung bestehen darin, Datenobjekte in einem Programm zu finden, auf die in Zukunft nicht mehr zugegriffen werden kann, und die von diesen Objekten verwendeten Ressourcen zurückzugewinnen. https://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29

Vorteile

1) Speichert vor Fehlern, die auftreten, wenn ein Speicherelement freigegeben wird, während noch Zeiger darauf vorhanden sind, und einer dieser Zeiger dereferenziert wird. https://en.wikipedia.org/wiki/Dangling_pointer

2) Doppelte freie Fehler, die auftreten, wenn das Programm versucht, einen Speicherbereich freizugeben, der bereits freigegeben und möglicherweise bereits wieder zugewiesen wurde.

3) Verhindert bestimmte Arten von Speicherlecks, bei denen ein Programm keinen Speicher freigeben kann, der von Objekten belegt wird, die nicht mehr erreichbar sind, was zu einer Speichererschöpfung führen kann.

Nachteile

1) Verbrauch zusätzlicher Ressourcen, Auswirkungen auf die Leistung, mögliche Verzögerungen bei der Programmausführung und Inkompatibilität mit der manuellen Ressourcenverwaltung. Die Speicherbereinigung verbraucht Rechenressourcen, um zu entscheiden, welcher Speicher freigegeben werden soll, obwohl der Programmierer diese Informationen möglicherweise bereits kennt.

2) Der Moment, in dem der Müll tatsächlich gesammelt wird, kann unvorhersehbar sein, was zu Verzögerungen (Pausen zum Verschieben / freien Speicher) führt, die über eine Sitzung verteilt sind. Unvorhersehbare Verzögerungen können in Echtzeitumgebungen, bei der Transaktionsverarbeitung oder in interaktiven Programmen nicht akzeptabel sein.


Oracle-Tutorial http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html

Bei der Speicherbereinigung wird ermittelt, welche Objekte verwendet werden und welche nicht, und die nicht verwendeten Objekte werden gelöscht.

In Programmiersprachen wie C, C ++ ist das Zuweisen und Freigeben von Speicher ein manueller Vorgang.

int * array = new int[size];
processArray(array); //do some work.
delete array; //Free memory

Der erste Schritt in diesem Prozess heißt Markieren. Hier identifiziert der Garbage Collector, welche Speicherelemente verwendet werden und welche nicht.

Schritt 2a. Beim normalen Löschen werden nicht referenzierte Objekte entfernt, sodass referenzierte Objekte und Zeiger auf freien Speicherplatz verbleiben.

Um die Leistung zu verbessern, möchten wir nicht referenzierte Objekte löschen und auch die verbleibenden referenzierten Objekte komprimieren. Wir möchten referenzierte Objekte zusammenhalten, damit schneller neuer Speicher zugewiesen werden kann.

Wie bereits erwähnt, ist es ineffizient, alle Objekte in einer JVM markieren und komprimieren zu müssen. Je mehr Objekte zugewiesen werden, desto größer wird die Liste der Objekte, was zu einer immer längeren Speicherbereinigungszeit führt.

Lesen Sie dieses Tutorial weiter und Sie werden wissen, wie GC diese Herausforderung annimmt.

Kurz gesagt, es gibt drei Bereiche des Heaps: YoungGeneration für Objekte mit kurzer Lebensdauer, OldGeneration für Objekte mit langer Lebensdauer und PermanentGeneration für Objekte, die während der Anwendungslebensdauer ausgeführt werden, z. B. Klassen und Bibliotheken.


0

Da Objekte vom neuen Operator dynamisch zugewiesen werden , können Sie fragen, wie diese Objekte zerstört werden und wie viel Speicherplatz freigegeben wird. In anderen Sprachen wie C ++ müssen Sie manuell zugewiesene Objekte dynamisch vom Löschoperator freigeben. Java hat einen anderen Ansatz; Die Freigabe erfolgt automatisch. Die Technik ist als Garbage Collection bekannt .

Dies funktioniert folgendermaßen: Wenn keine Verweise auf ein Objekt vorhanden sind, wird davon ausgegangen, dass dieses Objekt nicht mehr benötigt wird, und Sie können den vom Objekt belegten Speicher abrufen. Es ist nicht erforderlich, Objekte wie in C ++ explizit zu zerstören. Die Speicherbereinigung erfolgt sporadisch während der Programmausführung. Dies geschieht nicht einfach, weil ein oder mehrere Objekte nicht mehr verwendet werden. Darüber hinaus haben mehrere Java-Laufzeitimplementierungen unterschiedliche Ansätze für die Speicherbereinigung, aber die meisten Programmierer müssen sich beim Schreiben von Programmen keine Gedanken darüber machen.


-2

Die automatische Speicherbereinigung ist ein Prozess, bei dem die JVM bestimmte Datenpunkte entfernt oder im Speicher hält, um letztendlich Speicherplatz für das laufende Programm freizugeben. Der Speicher wird zuerst an den Heap-Speicher gesendet. Dort erledigt der Garbage Collector (GC) seine Arbeit und wird dann beendet oder aufbewahrt. Java geht davon aus, dass dem Programmierer nicht immer vertraut werden kann, und beendet daher Elemente, von denen er glaubt, dass sie nicht benötigt werden.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.