Vorwort
Ich habe eine Frage zu Segmentfault gesehen: Java hat einen vollständigen GC -Mechanismus, so wird es in Java ein Speicherleckproblem geben, und kann ich einen Fall von Speicherleck geben. Diese Frageansicht gibt die vollständige Antwort auf diese Frage.
Einführung in den Müllrecyclingmechanismus
Während des ausgeführten Programms wird jedes Objekt erstellt. Eine bestimmte Menge an Speicher wird für die Speicherung von Objektdaten zugewiesen. Wenn Sie nur weiterhin Speicher zuweisen, wird das Programm früher oder später vor dem Problem des unzureichenden Gedächtnisses konfrontiert. In jeder Sprache gibt es einen Mechanismus zur Wiederherstellung von Speicher, der die Erinnerung an abgelaufene Objekte frei macht, um sicherzustellen, dass der Speicher wiederverwendet werden kann.
Der Speicherrecycling -Mechanismus kann gemäß den Implementierungsrollen in zwei Typen unterteilt werden. Eine davon ist, dass Programmierer die Veröffentlichung von Gedächtnis (wie C-Sprache) manuell erkennen, und der andere ist der integrierte Speicherrecycling-Mechanismus der Sprache, wie den in diesem Artikel eingeführten Java-Müllsammlungsmechanismus.
Javas Müllsammlermechanismus
In der Laufzeitumgebung des Programms bietet die Java Virtual Machine einen Müllsammlungsthread auf Systemebene (GC, Carbage Collection). Die Voraussetzung für das Verständnis von GC ist es, einige Konzepte im Zusammenhang mit der Müllsammlung zu verstehen. Diese Konzepte werden im Folgenden nacheinander eingeführt.
Der Zustand des Objekts im JVM -Haufenbereich
Fälle von Java -Objekten werden im Haufen von JVM gespeichert. Für GC -Threads haben diese Objekte drei Zustände.
1. Berührbarer Zustand: Es gibt variable Referenzen im Programm, daher ist dieses Objekt Berührbarer Zustand.
2. Reaktivierter Zustand: Wenn sich keine Variablen im Programm auf dieses Objekt beziehen, ändert sich das Objekt von einem berührbaren Zustand in einen reaktivierten Zustand. Der CG -Thread bereitet sich darauf vor, die Abschlussmethode dieses Objekts zu einem bestimmten Zeitpunkt aufzurufen (die Abschlussmethode erbt oder umschreiben das untergeordnete Objekt um). Der Code in der Abschlussmethode kann das Objekt in einen berührbaren Status umwandeln, andernfalls wird das Objekt in einen unberührbaren Zustand umgewandelt.
3. Unberührbarer Zustand: Der GC -Thread kann den Speicher dieses Objekts nur dann recyceln, wenn sich das Objekt in einem unberührbaren Zustand befindet.
Um Objekte korrekt freizusetzen, muss GC den laufenden Status jedes Objekts, einschließlich der Anwendung, des Zitats, des Zitats, der Zuordnung usw., überwachen. GC muss sie überwachen, sodass GC egal ob ein Objekt in einem oben genannten Zustand ist.
Wie oben erwähnt, führen GC -Threads die Abschlussmethode für wiederbelebbare Zustandsobjekte zu einem bestimmten Zeitpunkt aus. Wann wird es ausgeführt? Da verschiedene JVM -Implementierer unterschiedliche Algorithmen verwenden können, um GC zu verwalten, können Entwickler jederzeit den Zeitpunkt von GC -Threads, die verschiedene Operationen ausführen, nicht vorhersagen (einschließlich Erkennung von Objektzuständen, Freisetzung von Objektspeichern und Aufrufen von Objekt -Abschlussmethoden). Obwohl der GC -Thread daran erinnert werden kann, dass die Funktionen von Müllsammlungen so bald wie möglich über das System.gc () und Runtime.gc () -Funktionen durchgeführt werden, kann dies nicht garantieren, dass der GC -Thread entsprechende Recyclingvorgänge sofort ausführt.
Speicherleck
Speicherlecks werden durch falsche Designs verursacht, dass das Programm nicht mehr verwendet wird, was nicht mehr verwendet wird, was zu Ressourcenverschwendung führt. GC säubert automatisch den Speicher, der von Objekten besetzt ist, die Referenzen verloren haben. Wenn jedoch aufgrund von Programmierfehlern immer auf einige Objekte verwiesen werden, tritt ein Speicherleck auf.
Zum Beispiel das folgende Beispiel. Ein Array wird verwendet, um einen Stapel mit zwei Vorgängen zu implementieren: Stapeleintrag und Stapelausgang.
Importieren Sie com.sun.javafx.collectionss.elementobservablelistDecorator; import com.sun.swing.internal.plaf.metal.resources.metal_sv; import Java.beans.ExceptionListener; */public class mystack {private Object [] Elemente; private int Increment = 10; private int size = 0; public mystack (int size) {Elements = neues Objekt [Größe]; } // den Stack public void push (Objekt o) {CAPAPY (); Elemente [Größe ++] = O; } // Das Stack Public Object pop () {if (size == 0) neue leereStackexception () werfen; Rückgabeelemente [-Größe]; } // Erhöhen Sie die Kapazität des Stapel private void capacity () {if (Elements.Length! = Größe) return; Object [] newArray = New Object [Elements.Length + Increment]; System.ArrayCopy (Elemente, 0, Newarray, 0, Größe); } public static void main (String [] args) {mystack stack = new mystack (100); für (int i = 0; i <100; i ++) stack.push (New Integer (i)); für (int i = 0; i <100; i ++) {System.out.println (stack.pop (). toString ()); }}}Dieses Programm ist verfügbar und unterstützt gemeinsame Operationen für Stack -Ein- und Stapeleintritt. Es gibt jedoch ein Problem, das nicht gut behandelt wurde. Wenn der Stapelvorgang freigegeben wird, wird der Verweis auf das Stapelelement im Array nicht freigegeben, wodurch das Programm einen Verweis auf dieses Objekt beibehält (dieses Objekt wird vom Array verwiesen). GC glaubt immer, dass dieses Objekt zugänglich ist, was bedeutet, dass es nicht erforderlich ist, über die Freigabe seines Gedächtnisses zu sprechen. Dies ist ein typischer Fall von Speicherlecks. Dafür lautet der geänderte Code:
// stapel public Object pop () {if (size == 0) werfen neue leereStackexception (); Objekt o = Elemente [-Größe]; Elemente [Größe] = NULL; Rückkehr O; }Der obige Artikel hat ein tiefes Verständnis des Mechanismus für Java -Garbage -Sammlung und des Speicherlecks. Dies ist alles der Inhalt, den ich mit Ihnen geteilt habe. Ich hoffe, es kann Ihnen eine Referenz geben und ich hoffe, Sie können Wulin.com mehr unterstützen.