Dieser Artikel ist ein Spiegelartikel der maschinellen Übersetzung, bitte klicken Sie hier, um zum Originalartikel zu springen.

Ansehen: 12807|Antwort: 0

[JavaSE] Erlangen Sie ein tiefgehendes Verständnis von Javas Müllabholmechanismus

[Link kopieren]
Veröffentlicht am 04.12.2017 20:26:51 | | |
1. Die Bedeutung des Müllrecyclingmechanismus  
Ein bemerkenswertes Merkmal der Java-Sprache ist die Einführung eines Garbage Collection-Mechanismus, der das problematischste Speichermanagementproblem für C++-Programmierer löst, sodass Java-Programmierer beim Programmschreiben kein Speichermanagement mehr berücksichtigen müssen. Aufgrund des Garbage Collection-Mechanismus haben Objekte in Java das Konzept des "Scope" nicht mehr, sondern nur die Referenz des Objekts hat einen "Scope".Garbage Collection kann Speicherlecks effektiv verhindern und ungenutzten Speicher effektiv nutzen.

ps:内存泄露是指该内存空间使用完毕之后未回收,在不涉及复杂数据结构的一般情况下,Java 的内存泄露表现为一个内存对象的生命周期超出了程序需要它的时间长度,我们有时也将其称为“对象游离”。
2. Algorithmen in Garbage Collection-Mechanismen  
Die Java-Sprachspezifikation legt nicht explizit fest, welchen Garbage Collection-Algorithmus im JVM verwendet werden soll, aber jeder Garbage Collection-Algorithmus muss im Allgemeinen zwei grundlegende Dinge tun: (1) nutzlose Informationsobjekte finden; (2) Den von nutzlosen Objekten belegten Speicherplatz zurückgewinnen, sodass der Speicher vom Programm wieder genutzt werden kann.
1. Referenzzähler-Sammler
1.1 Algorithmusanalyse

Referenzzählen ist eine frühe Strategie bei Müllsammeln. Bei diesem Ansatz gibt es für jede Objektinstanz im Heap eine Referenzanzahl. Wenn ein Objekt erstellt wird und die Objektinstanz einer Variablen zugewiesen wird, wird die Variablenanzahl auf 1 gesetzt. Wenn eine andere Variable als Referenz für dieses Objekt zugewiesen wird, wird die Anzahl um 1 addiert (a = b, dann ist der Zähler der von b referenzierten Objektinstanz +1), aber wenn eine Referenz auf eine Objektinstanz ihre Lebensdauer überschritten hat oder auf einen neuen Wert gesetzt wird, wird der Referenzzähler der Objektinstanz um 1 subtrahiert. Jede Instanz eines Objekts mit einem Referenzzähler von 0 kann als Müll gesammelt werden. Wenn eine Objektinstanz als Garbage Collect durchgeführt wird, beträgt der Referenzzähler jeder von ihr referenzierten Objektinstanz minus 1.
1.2 Vor- und Nachteile
Verdienst:

Der Referenzzähl-Sammler kann sehr schnell ausgeführt werden und in den Programmlauf eingewoben werden. Es ist vorteilhaft für Echtzeitumgebungen, in denen Programme nicht über längere Zeiträume unterbrochen werden müssen.
Mangel:

Kreisförmige Bezüge können nicht erkannt werden. *Wenn das Elternobjekt eine Referenz auf ein Kindobjekt hat, bezieht sich das Kindobjekt wiederum auf das Elternobjekt. Auf diese Weise kann ihre Zitationszahl niemals 0 sein.
1.3 Der Referenzzählalgorithmus kann das zirkuläre Referenzproblem nicht lösen, zum Beispiel:
/** * Java学习交流QQ群:589809992 我们一起学Java! */public class Main {    public static void main(String[] args) {        MyObject object1 = new MyObject();        MyObject object2 = new MyObject();        object1.object = object2;        object2.object = object1;        object1 = null;        object2 = null;    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  
Die letzten beiden Sätze ordnen Objekt1 und Objekt2 Null zu, was bedeutet, dass die von Objekt1 und Objekt2 gezeigten Objekte nicht mehr zugänglich sind, aber da sie aufeinander verweisen, sind ihre Referenzzähler nicht 0, sodass der Müllabnehmer sie niemals recyceln wird.
2. Tracing Collector oder Mark-and-Sweep-Algorithmus
2.1 Wurzelsuchalgorithmus


Der Root-Suchalgorithmus wurde aus der Graphentheorie in der diskreten Mathematik eingeführt; das Programm betrachtet alle Referenzbeziehungen als einen Graphen, beginnend mit einem GC-ROOT-Knoten, sucht nach dem entsprechenden Referenzknoten; nachdem dieser Knoten gefunden wurde, sucht man weiter nach dem Referenzknoten dieses Knotens; wenn alle Referenzknoten durchsucht wurden, gelten die übrigen Knoten als unreferenzierte Knoten, also nutzlose Knoten.
Java, das als GC-Root verwendet werden kann
1. Objekte, die im Virtual-Machine-Stack referenziert werden (lokale Variablentabelle)
2. Das Objekt, das durch das statische Attribut im Methodenbereich referenziert wird
3. Das Objekt, das durch die Konstante im Methodenbereich referenziert wird
4. Referenzierte Objekte im lokalen Methodenstack (native Objekte)
2.2 Schematisches Diagramm des Nachverfolgungsalgorithmus

2.3 Analyse des Markierungs-Clearing-Algorithmus

Der Tag-Purge-Algorithmus scannt aus der Wurzelsammlung, markiert die überlebenden Objekte und scannt dann den gesamten Raum nach ungetaggten Objekten zum Recycling, wie in der obigen Abbildung gezeigt. Der Tag-Purge-Algorithmus muss keine Objekte bewegen und verarbeitet nur nicht überlebende Objekte, was bei vielen überlebenden Objekten äußerst effizient ist, aber da der Tag-Purge-Algorithmus nicht überlebende Objekte direkt recycelt, führt dies zu Speicherfragmentierung.
3. Kompaktierungsalgorithmus oder Label-Finishing-Algorithmus


Der Tag-Finish-Algorithmus verwendet dieselbe Methode wie der Tag-Clear-Algorithmus zur Beschriftung von Objekten, ist jedoch beim Säubern anders: Nachdem der von nicht überlebende Objekte eingenommene Speicherplatz zurückerobert wurde, werden alle überlebenden Objekte in den freien Platz am linken Ende verschoben und der entsprechende Zeiger aktualisiert. Der Tag-Finish-Algorithmus basiert auf dem Tag-Purge-Algorithmus und bewegt Objekte, daher ist er teurer, löst aber das Problem der Speicherfragmentierung. Bei der Implementierung von Kollektoren auf Basis des Compacting-Algorithmus werden in der Regel Handles und Handle-Tabellen hinzugefügt.
4. Kopierungsalgorithmus (Kompakter-Kollektor)


Der Algorithmus wird vorgeschlagen, um den Overhead des Handles zu überwinden und die Garbage Collection von Heap-Debris zu lösen. Wenn das Objekt voll ist, scannt die Garbage Collection basierend auf dem Kopieralgorithmus das aktive Objekt aus der Wurzelmenge und kopiert jedes aktive Objekt auf die freie Fläche (sodass keine freien Löcher zwischen dem vom aktiven Objekt belegten Speicher entstehen), sodass die freie Fläche zur Objektfläche wird, die ursprüngliche Objektfläche zur freien Fläche und das Programm Speicher an der neuen Objektfläche zuweist. Eine typische Garbage Collection, die auf dem Coping-Algorithmus basiert, ist der Stop-and-Copy-Algorithmus, der den Heap in Objektflächen und freie Flächenflächen unterteilt und das Programm die Ausführung während des Wechsels zwischen Objektflächen und freien Flächen pausiert.
5. Generationaler Sammler


Die generationenübergreifende Müllrecyclingstrategie basiert darauf, dassDer Lebenszyklus verschiedener Objekte ist unterschiedlich。 Daher können Objekte mit unterschiedlichen Lebenszyklen unterschiedliche Recyclingalgorithmen übernehmen, um die Recyclingeffizienz zu verbessern.
Junge Generation
1. Alle neu generierten Objekte werden zuerst der jüngeren Generation zugeordnet. Das Ziel der jüngeren Generation ist es, diese Objekte mit einem kurzen Lebenszyklus so schnell wie möglich zu sammeln.

2. Der Speicher der neuen Generation ist in eine Eden-Region und zwei Überlebendenzonen (Überlebender0, Überlebender1) gemäß dem Verhältnis 8:1:1 unterteilt. Eine Eden-Zone, zwei Überlebenszonen (im Allgemeinen). Die meisten Objekte werden im Eden-Gebiet gespawnt. Wenn der Survivor0-Bereich ebenfalls voll ist, werden der Eden-Bereich und der Survivor-0-Bereich in einen anderen Survivor1-Bereich kopiert, dann werden der Eden- und Survivor0-Bereich geleert, dann ist der Survivor0-Bereich leer, und dann werden der Survivor0-Bereich und der Survivor1-Bereich ausgetauscht. Das heißt, den Überlebenden1-Bereich leer halten und so weiter.

3. Wenn der Bereich Survivor 1 nicht ausreicht, um die überlebenden Objekte von Eden und Survivor0 zu lagern, werden die überlebenden Objekte direkt in die alte Ära gelagert. Wenn das Alter ebenfalls voll ist, löst das einen vollständigen GC aus, das heißt, die neue und die alte Generation werden recycelt

4. Der GC der neuen Generation wird auch Minor GC genannt, und die Häufigkeit von MinorGC ist relativ hoch (er wird nicht unbedingt ausgelöst, wenn das Eden-Gebiet voll ist)
Alte Generation

1. Objekte, die nach dem N-Müllrecycling in der jüngeren Generation noch lebendig sind, werden in die ältere Generation gebracht. Daher kann man annehmen, dass die alte Generation in einigen Objekten mit einem langen Lebenszyklus gespeichert ist.

2. Das Gedächtnis ist auch deutlich größer als das der neuen Generation (das ungefähre Verhältnis beträgt 1:2), wenn das Gedächtnis des Alters voll ist, wird das Major GC ausgelöst, also das vollständige GC, ist die Häufigkeit des vollen GC relativ niedrig, die Überlebenszeit des Altersobjekts relativ lang und die Überlebensrate hoch.
Ständige Erzeugung
Wird verwendet, um statische Dateien wie Java-Klassen, Methoden usw. zu speichern. Persistente Generierungen haben keinen signifikanten Einfluss auf die Garbage Collection, aber einige Anwendungen können dynamisch bestimmte Klassen wie Hibernate usw. generieren oder aufrufen, und in diesem Fall muss ein relativ großer Speicherplatz für persistente Generierungen eingestellt werden, um diese neuen Klassen während der Laufzeit zu speichern.
3. GC (Müllmann)Sammler, die von der neuen Generation verwendet werden: Serial, PraNew, Parallel Scavenge
Sammler, die von Altensammlern verwendet werden: Seriell Alt, Parallel Alt, CMS

Serieller Sammler (Replikationsalgorithmus)
Die neue Generation der Eingewindensammler, Markierung und Reinigung, ist Eingewinde, mit dem Vorteil, einfach und effizient zu sein.
Serieller alter Sammler (Label-Finish-Algorithmus)
Old Age Single Thread Collector, Old Age Version des Serial Collector.
ParNew-Sammler (Stop-Copy-Algorithmus)
Die neue Generation des Kollektors kann als Multi-Thread-Version des Seriellen Kollektors betrachtet werden, der in einer Mehrkern-CPU-Umgebung eine bessere Leistung als Seriell-Kollektor bietet.
Paralleler Scavenge Collector (Stop-Copy-Algorithmus)
Parallelkollektoren für hohen Durchsatz und effiziente CPU-Auslastung. Der Durchsatz beträgt in der Regel 99 %, und der Durchsatz = Benutzer-Thread-Zeit / (Benutzer-Thread-Zeit + GC-Thread-Zeit). Es eignet sich für Szenarien wie Hintergrundanwendungen, die entsprechend keine hohe Interaktion erfordern.
Paralleler alter Sammler (Stop-Copy-Algorithmus)
Eine ältere Version des Parallel Scavenge-Kollektors, ein Parallelkollektor mit Durchsatzpriorität
CMS (Concurrent Mark Sweep) Collector (Mark-Clean-Algorithmus)
Hohe Nebenzeitigkeit, geringe Pause, die kürzeste GC-Wiederherstellungspause, hohe CPU-Auslastung, schnelle Reaktionszeit, kurze Pausenzeit und Multi-Core-CPU mit hoher Antwortzeit
4. Der Umsetzungsmechanismus von GCDa das Objekt in verschiedenen Generationen verarbeitet wurde, unterscheiden sich auch Fläche und Zeit der Müllabfuhr. Es gibt zwei Arten von GCs: Scavenge GC und Full GC.
Scavenge GC
Normalerweise wird der Scavenge GC ausgelöst, wenn ein neues Objekt generiert wird und keinen Platz in Eden beantragen kann, wodurch der GC den Eden-Bereich auslöst, nicht überlebende Objekte beseitigt und die überlebenden Objekte in den Überlebendenbereich bringt. Dann sortiere die beiden Zonen von Survivor. GC wird auf diese Weise im Eden-Gebiet der jüngeren Generation durchgeführt und betrifft die ältere Generation nicht. Da die meisten Objekte im Eden-Gebiet beginnen und das Eden-Gebiet nicht sehr viel zugewiesen ist, wird der GC des Eden-Gebiets häufig durchgeführt. Daher ist es im Allgemeinen notwendig, hier schnelle und effiziente Algorithmen zu verwenden, um Eden so schnell wie möglich frei zu machen.
Vollwertige Gesamtwertung
Organisieren Sie den gesamten Stapel, einschließlich Young, Tenured und Perm. Full-GC ist langsamer als Scavenge GC, weil der gesamte Haufen recycelt werden muss, daher sollte die Anzahl der Full GCs so weit wie möglich reduziert werden. Ein großer Teil des JVM-Tuning-Prozesses ist das Tuning von FullGC. Volles GC kann durch folgende Gründe verursacht werden:
1. Tenured ist voll geschrieben
2. Perm ist voll geschrieben  
3. System.gc() wird als Aufruf angezeigt  
4. Die Domänenallokationsstrategie von Heap ändert sich dynamisch nach dem letzten GC
5. Java mit GC hat ebenfalls Speicherleckprobleme1. Die Verwendung statischer Sammelklassen wie HashMap, Vector usw. ist am anfälligsten für Speicherlecks, und der Lebenszyklus dieser statischen Variablen ist derselbe wie der der Anwendung, und alle Objekte können nicht freigegeben werden, da sie immer von Vector und anderen angewendet werden.
Statischer Vektor v = neuer Vektor(); für (int i = 1; i<100; i++) { Objekt o = neues Objekt();     v.add(o);     o = null; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  
In diesem Beispiel gibt es eine Referenz v für das Vector-Objekt und eine Referenz o für das Objekt-Objekt im Code-Stack. In der For-Schleife generieren wir immer wieder neue Objekte, fügen sie dann dem Vector-Objekt hinzu und löschen anschließend die o-Referenz auf. Die Frage ist: Wenn die O-Referenz aufgehoben wird und GC auftritt, kann das von GC erstellte Objektobjekt von GC recycelt werden? Die Antwort ist nein. Denn wenn GC Referenzen im Code-Stack verfolgt, findet es v-Referenzen, und wenn du weiter nachverfolgst, wirst du feststellen, dass es Referenzen auf Objektobjekte im Speicherbereich gibt, auf die v-Referenzen hinweisen. Das bedeutet, dass auch wenn die O-Referenz geleert wurde, noch andere Referenzen auf das Objektobjekt zugänglich sind, sodass der GC diese nicht freigeben kann. Wenn nach dieser Schleife das Objektobjekt keinen Einfluss mehr auf das Programm hat, nehmen wir an, dass das Java-Programm ein Speicherleck hat.
2. Verschiedene Verbindungen, Datenbankverbindungen, Netzwerkverbindungen, IO-Verbindungen usw. zeigen den Anruf nicht als nahe bis geschlossen an und werden von GC nicht recycelt, was zu Speicherlecks führt.
3. Der Einsatz von Zuhörern kann auch zu Gedächtnisverlusten führen, wenn der Zuhörer beim Losgeben des Objekts nicht gelöscht wird.




Vorhergehend:Neulinge spielen etwas schwarze Technologie in CSS
Nächster:Vorsicht vor dem Wanke Cloud Snap Softwarevirus Trojaner!
Verzichtserklärung:
Alle von Code Farmer Network veröffentlichten Software, Programmiermaterialien oder Artikel dienen ausschließlich Lern- und Forschungszwecken; Die oben genannten Inhalte dürfen nicht für kommerzielle oder illegale Zwecke verwendet werden, andernfalls tragen die Nutzer alle Konsequenzen. Die Informationen auf dieser Seite stammen aus dem Internet, und Urheberrechtsstreitigkeiten haben nichts mit dieser Seite zu tun. Sie müssen die oben genannten Inhalte innerhalb von 24 Stunden nach dem Download vollständig von Ihrem Computer löschen. Wenn Ihnen das Programm gefällt, unterstützen Sie bitte echte Software, kaufen Sie die Registrierung und erhalten Sie bessere echte Dienstleistungen. Falls es eine Verletzung gibt, kontaktieren Sie uns bitte per E-Mail.

Mail To:help@itsvse.com