In Java enthält seine Speicherverwaltung zwei Aspekte: Speicherzuweisung (beim Erstellen von Java -Objekten) und Speicherrecycling. Beide Aspekte der Arbeit werden vom JVM automatisch abgeschlossen, wodurch die Schwierigkeit des Lernens für JAVA -Programmierer verringert und die Gefahr des direkten Betriebsspeichers wie C/C ++ vermieden wird. Genau dessen, dass die Speicherverwaltung von der JVM vollständig behandelt wird, kümmert sich viele Java -Programmierer nicht mehr um Speicherzuweisung, was dazu führt, dass viele Programme ineffizient sind und Speicherkonsumenten konsumieren. Daher sollten Java -Programmierer die JVM am Ende verstehen, um effizientere Programme zu schreiben und den begrenzten Speicher vollständig zu nutzen.
1. Javas Zustand im Gedächtnis
Lassen Sie uns zunächst einen Code als Beispiel schreiben:
Person.java
Pakettest; import Java.io.Serializable; öffentliche Klasse implementiert serialisierbar {statische endgültige long serialversionuid = 1l; Zeichenfolge Name; // Personenfreund nennen; // Friends public Person () {} public person (String name) {Super (); this.name = name; }} Test.java
Pakettest; public class Test {public static void main (String [] args) {Person p1 = new Person ("Kevin"); Person p2 = neue Person ("Regen"); Person p3 = neue Person ("sonnig"); p1.freund = p2; p3 = p2; p2 = null; }} Wenn Sie die Objektreferenz im Hauptaspekt in test.java oben in ein Objektreferenzdiagramm aus der Hauptmethode zeichnen, ist dies so (Scheitelpunkte sind Objekte und Referenzen, und gerichtete Kanten sind Referenzbeziehungen):
Wenn das Programm ausgeführt wird, kann es nach dem angesehenen Graph in drei Typen unterteilt werden:
1) erreichbarer Zustand: Nachdem ein Objekt erstellt wurde, bezieht sich mehr als eine Referenzvariable darauf. In einem gerichteten Diagramm können Sie vom Startscheitel zum Objekt navigieren und sich in einem zugänglichen Zustand befinden.
2) Wiederherstellbarer Status: Wenn ein Objekt im Programm keine Referenzvariablen mehr hat, die sich darauf bezieht, wird zunächst der restaurierbare Zustand eingegeben und kann zu diesem Zeitpunkt nicht vom Startscheitel des angegebenen Diagramms zum Objekt navigieren. In diesem Zustand ist der Mülleimersammler des Systems bereit, den vom Objekt besetzten Speicher zu recyceln. Vor dem Recycling ruft das System die methode finalize () auf, um die Ressource zu bereinigen. Wenn mehr als eine Referenzvariable nach Sortierung der Ressource zurückgefordert wird, wird das Objekt wieder zu einem zugänglichen Zustand. Andernfalls tritt es in einen unerreichbaren Zustand ein.
3) Nicht erreichbarer Zustand: Wenn alle Assoziationen des Objekts abgeschnitten werden und das System die Finalize () -Methode aufruft, um die Ressource zu säubern, wird der Objekt immer noch nicht erreichbar, dann verliert das Objekt dauerhaft Referenz und wird nicht erreichbar, und das System recycelt die vom Objekt besetzten Ressourcen wirklich.
Das Übergangsdiagramm der obigen drei Zustände lautet wie folgt:
2. Verweise auf Objekte von Java
1) Starke Referenz: Erstellen Sie ein Objekt und weisen Sie dieses Objekt einer Variablen direkt zu, z. B. Person Person = New Person ("Sunny"); Unabhängig davon, wie eng die Systemressourcen sind, wird das stark referenzierte Objekt niemals recycelt, auch wenn es in Zukunft nicht erneut verwendet wird.
2) Weiche Referenz: Implementiert durch die SofTreference -Klasse, z. B. SofTreference <Person> p = New Softrreference <Person> (Neue Person ("Regen"); Wenn der Speicher sehr eng ist, wird es recycelt und wird nicht recycelt, und es wird nicht recycelt.
3) Schwache Referenz: Implementiert durch die WeaCreference -Klasse, z. Unabhängig davon, ob der Speicher ausreicht, wird das System während der Müllsammlung definitiv recycelt.
4) Virtuelles Zitat: Es kann nicht allein verwendet werden, es wird hauptsächlich verwendet, um den Zustand des gesammelten Objekts zu verfolgen. Implementiert durch die PhantomReference -Klasse und die Referenzwarteschlange Referencequeue -Klasse, z. B.:
Pakettest; importieren java.lang.ref.phantomReference; import Java.lang.Ref.Referencequeue; public class Test {public static void main (String [] args) {// Erstellen einer Objektperson = neue Person ("sonnig"); // Erstellen Sie eine Referenzwarteschlange Referenzqueue <Person> rq = new Referencequeue <Person> (); // Erstellen Sie eine virtuelle Referenz. Lassen Sie diese virtuelle Referenz auf das Personobjekt -PhantomReference <Person> pr = New PhantomReference <Person> (Person, RQ) verweisen. // Die Referenzvariablen und -Objekte der Person referenzieren person = null; // Versuchen Sie, das von der virtuelle Referenz verwiesene Objekt herauszuholen // Ich habe festgestellt, dass das Programm nicht über die virtuelle Referenz auf das referenzierte Objekt zugreifen kann, daher ist die Ausgabe null system.out.println (pr.get ()); // erzwungene Müllsammlungssystem.gc (); System.Runfinalisierung (); // Denn sobald das Objekt in der virtuellen Referenz recycelt ist, wird die virtuelle Referenz die Referenzwarteschlange eingibt // Verwenden Sie also die Referenz, die zuerst die Warteschlange in der Warteschlange eingebracht hat, um mit PR zu vergleichen, und true System.out.Out.println (rq.poll () == PR); }}Auslaufergebnisse:
3. Mechanismus für Java -Müllsammlung
Tatsächlich macht Java Müllsammlung hauptsächlich zwei Dinge: 1) Speicherrecycling 2) Defragmentierung
3.1 Algorithmus für Müllsammeln
1) serielles Recycling (nur eine CPU) und paralleles Recycling (mehrere CPUs sind nützlich): Serielles Recycling bedeutet, dass das System unabhängig davon, wie viele CPUs das System hat, immer nur eine CPU zur Durchführung von Müllabfuhrvorgängen ist. Paralleles Recycling bedeutet, die gesamte Recyclingarbeit in mehrere Teile aufzuteilen, wobei jeder Teil von einer CPU verantwortlich ist, sodass mehrere CPUs parallel recycelt werden können. Das parallele Recycling ist bei der Ausführung sehr effizient, erhöht jedoch die Komplexität, und es gibt auch einige Nebenwirkungen, wie z. B. zufälliger Anstieg des Gedächtnisses.
2) Gleichzeitige Ausführung und Anwendungsstopp: Wie der Name schon sagt, verursacht seine Müllansammlungsmethode bei der Durchführung der Müllsammlung eine Bewerbungsaufhängung. Obwohl die Müllsammlung gleichzeitiger Ausführung nicht dazu führt, dass die Anwendung innehalten wird, da gleichzeitige Ausführungsmüllkonflikte Konflikte mit der Anwendung lösen müssen (die Anwendung kann Objekte während des Müllsammlungsprozesses ändern), ist der Systemaufwand der gleichzeitigen Ausführung der Müllsammlung beim Ausführen von Müll höher als die der Ausführung von Müll.
3) Komprimieren und Nichtkompress und Kopie:
① Der Müllkollektor, der die Komprimierung (mark-compression = mark-clare + komprimiert) unterstützt, verlagert alle erreichbaren Objekte zusammen und recyceln dann alle zuvor besetzten Speicher, wodurch die Speicherfragmentierung verringert wird.
② Der unkomprimierte Müllsammler (marke clear) muss zweimal durchquert werden. Wenn Sie zum ersten Mal auf alle erreichbaren Objekte zugreifen und sie als erreichbare Zustände markieren. Beim zweiten Mal erleichtern Sie den gesamten Speicherbereich und recyceln Objekte, die nicht mit den erreichbaren Zuständen gekennzeichnet sind. Diese Recycling -Methode ist nicht komprimiert und erfordert keinen zusätzlichen Speicher, erzeugt jedoch Fragmentierung, wenn zwei Travers erforderlich sind.
③ Müllkollektor kopieren: Teilen Sie den Heap -Speicher in zwei identische Räume auf, greifen Sie auf jedes zugeordnete erreichbare Objekt aus dem Wurzel zu (ähnlich dem Startscheitel des vorherigen angegebenen Diagramms), kopieren Sie alle erreichbaren Objekte in Raum A bis Raum B und recyceln Speicherplatz A gleichzeitig. Für diesen Algorithmus, da Sie nur auf alle erreichbaren Objekte zugreifen müssen, alle erreichbaren Objekte wegkopieren und den gesamten Raum direkt recyceln und die nicht erreichbaren Objekte überhaupt ignorieren, sind die Kosten für das Durchlaufen des Raums gering, erfordert jedoch enorme Kopierkosten und mehr Speicher.
3.2 Generationenrecycling des Heap -Speichers
1) Die Grundlage für das Recycling von Generationen:
①Die Länge der Überlebenszeit des Objekts: Die meisten Objekte werden während der jungen Periode recycelt.
2) Erzeugung des Heap -Speichers:
① junge Generation:
ⅠRecycling -Mechanismus: Da die Anzahl der Objekte klein ist, werden Replikation und Recycling verwendet.
Ⅱ Konsolidierungsgebiet: Es besteht aus 1 Eden Area und 2 Survivor -Gebieten. Zwei Überlebendebereiche gleichzeitig wird eins verwendet, um das Objekt zu retten, und der andere ist leer. Jedes Mal, wenn die Müllsammlung der jungen Generation durchgeführt wird, werden die zugänglichen Objekte in Eden und von in den Bereich in den Bereich kopiert, und einige der langlebigen werden in das Alter kopiert, dann wird der Eden und aus dem Weltraum geräumt, und schließlich wird das Original in den Weltraum aus dem Raum, und das Original vom Raum wird zum Weltraum.
Ⅲ Objektquelle: Die meisten Objekte werden zuerst dem Eden -Bereich zugeordnet, und einige große Objekte werden der alten Generation direkt zugeordnet.
Ⅳ Recyclingfrequenz: Da die meisten Objekte der jungen Generation schnell in einen unerreichbaren Zustand eintreten, ist die Recyclingfrequenz hoch und die Recyclinggeschwindigkeit ist schnell.
②old Generation:
ⅠRecycling -Mechanismus: Verwenden Sie den Mark -Komprimierungsalgorithmus zur Wiederherstellung.
Ⅱ Objektquelle: 1. Das große Objekt tritt direkt in das Alter ein.
2. Recyclingfrequenz erreichbarer Objekte mit langer Überlebenszeit in der jungen Generation: Da nur wenige Objekte sterben, ist die Ausführungsfrequenz nicht hoch und es dauert lange, bis es fertig ist.
③permanente Generation:
ⅠPurpose: Wird zum Laden von Klasse, Methode und anderen Informationen verwendet. Der Standard ist 64 m und wird nicht recycelt. ⅡObject Source: z. Daher begegnen wir oft Java.lang.outofMemoryError: Permgen -Raumfehler beim Debuggen von Winterschlaf. Dies ist der Fehler, der durch die Erschöpfung der permanenten Gedächtniserzeugung verursacht wird.
Ⅲ Recyclingfrequenz: wird nicht recycelt
3.3 Müllsammler
1) Serienrecycler (nur eine CPU wird verwendet): Die junge Generation verwendet einen seriellen Kopieralgorithmus; Die alte Generation verwendet den Serienmarkierungskomprimierungsalgorithmus (drei Stufen: Marke - Clear Sweep - Compress Compact). Das Programm wird während der Recyclingperiode durchgeführt.
2) Paralleler Recycler: Der für die junge Generation verwendete Algorithmus ist der gleiche wie der serielle Recycler, fügt jedoch nur eine parallele Multi-CPU-Verarbeitung hinzu. Die Verarbeitung der alten Generation ist genau die gleiche wie die des seriellen Recyclers und immer noch ein einzelner Thread.
3) Parallelkompressionskollektor: Die Verarbeitung der jungen Generation ist genau der gleiche Algorithmus wie der des parallelen Sammlers; Für die alte Generation werden jedoch unterschiedliche Algorithmen verwendet, die tatsächlich in verschiedene Regionen unterteilt sind und dann den Algorithmus für Kenn- und Komprimierungsträger:
① Alt in mehrere feste Bereiche unterteilen;
② MARK-BETAGE (Multi-Threaded-Parallele), markierende erreichbare Objekte;
③ Zusammenfassungsphase (serielle Ausführung). Wenn Sie einen Bereich finden, der den numerischen Wert (niedrige Objektdichte) von links erreicht, werden dieser Bereich und sein rechter Bereich komprimiert und wiederhergestellt. Das linke Ende ist der dichte Bereich ④ kompakte Stufe (Multi-Thread-parallel), identifizieren die Bereiche, die geladen werden müssen, und kopieren die Daten parallel in diese Bereiche. Nach diesem Prozess gibt es eine große Anzahl aktiver Objekte an einem Ende der alten Generation und ein großes Stück Platz am anderen Ende.
4) gleichzeitige Identifizierung - Reinigung und Recycling (CMS): Die Verarbeitung der jungen Generation ist genau der gleiche Algorithmus wie die parallelen Recycler; Für die alte Generation werden jedoch verschiedene Algorithmen verwendet, aber der Mark -Reinigungsalgorithmus wird weiterhin verwendet:
① Erstidentifikation (Programm Pause): markiert das direkt verwiesene Objekt (Objekt auf erste Ebene);
② Gleichzeitige Identifizierung (Programmlauf): Weitere erreichbare Objekte finden Sie in Objekten erster Ebene;
③ RE-Marke (Programm Pause): Multi-Thread-Parallel-Re-markierende Objekte, die aufgrund von Parallelität möglicherweise übersehen wurden (einfach sprechend, ist es gegen das Missing)
④ gleichzeitige Reinigung (Programmläufe)
4. Tipps zur Speicherverwaltung
1) Versuchen Sie, die direkte Menge zu verwenden, z. B. String javastr = "Der Wachstumsprozess der Grundschule Ausbildung";
2) Verwenden Sie StringBuilder und StringBuffer, um die String -Verkettung und andere Operationen durchzuführen.
3) Freisetzende nutzlose Objekte so schnell wie möglich freigeben;
4) Versuchen Sie, so wenig wie möglich statische Variablen zu verwenden.
5) Cache häufig verwendete Objekte: Kann mit Open Source Open Source -Cache implementiert werden, z. B. Oscache, EHCache;
6) Versuchen Sie, die Methode Finalize () nicht zu verwenden.
7) Sie können bei Bedarf eine weiche Referenzweichweite verwenden.
Das obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, es wird für das Lernen aller hilfreich sein und ich hoffe, jeder wird Wulin.com mehr unterstützen.