Tiefes Verständnis des JVM ==> Laufzeitdatenbereichs

1. Einführung in JVM

  JVM ist eine Abkürzung für Java Virtual Machine (Java Virtual Machine). JVM ist eine Spezifikation für Computergeräte. Es handelt sich um einen fiktiven Computer, der durch Simulation verschiedener Computerfunktionen auf einem tatsächlichen Computer realisiert wird.

  Ein sehr wichtiges Merkmal der Java-Sprache ist ihre plattformübergreifende Natur. Die Verwendung einer virtuellen Java-Maschine ist der Schlüssel, um diese Funktion zu erreichen. Wenn eine allgemeine Hochsprache auf verschiedenen Plattformen ausgeführt werden soll, muss sie zumindest in verschiedene Objektcodes kompiliert werden. Nach der Einführung der virtuellen Maschine in Java muss die Java-Sprache nicht neu kompiliert werden, wenn sie auf verschiedenen Plattformen ausgeführt wird. Die Java-Sprache verwendet die Java Virtual Machine, um Informationen zu bestimmten Plattformen abzuschirmen, sodass der Java Language Compiler nur den Zielcode (Bytecode) generieren muss, der auf der Java Virtual Machine ausgeführt wird und ohne Änderungen auf mehreren Plattformen ausgeführt werden kann. . Wenn die Java Virtual Machine Bytecode ausführt, interpretiert sie den Bytecode als Maschinenanweisungen auf einer bestimmten Plattform zur Ausführung. Aus diesem Grund kann Java "einmal kompilieren, überall ausführen".

Zwei, JVM-Speicherverwaltungsmodell

Heapspeicher (Heap)

  Für die meisten Anwendungen ist der Java-Heap der größte Speicher, der von der Java Virtual Machine verwaltet wird. Der Java-Heap ist ein Speicherbereich, der von allen Threads gemeinsam genutzt und beim Start der virtuellen Maschine erstellt wird. Der einzige Zweck dieses Speicherbereichs besteht darin, Objektinstanzen zu speichern, in denen fast allen Objektinstanzen Speicher zugewiesen wird.

  Der Java-Heapspeicher kann auch unterteilt werden in: junge und alte Generation. Unter diesen kann die junge Generation in den Eden-Bereich, den Raum des Überlebenden, den Raum des Überlebenden usw. unterteilt werden.

  Wenn der Heap keinen Speicher zum Abschließen der Instanzzuweisung enthält und der Heap nicht mehr erweitert werden kann, wird eine OutOfMemoryError-Ausnahme ausgelöst.

Methodenbereich

  Der Methodenbereich (Methodenbereich) ist wie der Java-Heap ein Speicherbereich, der von verschiedenen Threads gemeinsam genutzt wird. Er wird zum Speichern von Daten wie Klasseninformationen, Konstanten, statischen Variablen und Code verwendet, die vom Echtzeit-Compiler kompiliert wurden und von der virtuellen Maschine geladen wurden. Obwohl die Java Virtual Machine-Spezifikation den Methodenbereich als logischen Teil des Heaps beschreibt, hat sie einen Alias ​​namens Non-Heap (Nicht-Heap). Der Zweck sollte vom Java-Heap unterschieden werden.

  Für Entwickler, die es gewohnt sind, Programme auf virtuellen HotSpot-Maschinen zu entwickeln und bereitzustellen, sind viele Menschen bereit, den Methodenbereich "Permanent Generation" zu nennen. Im Wesentlichen sind die beiden nicht gleichwertig, nur aufgrund der virtuellen HotSpot-Maschinen Das Designteam entschied sich dafür, die GC-Generierungssammlung auf den Methodenbereich auszudehnen oder die permanente Generierung zur Implementierung des Methodenbereichs zu verwenden.

  Die Java Virtual Machine-Spezifikation unterliegt sehr lockeren Einschränkungen in diesem Bereich. Zusätzlich zum Java-Heap, der keinen zusammenhängenden Speicher benötigt und fest oder erweiterbar sein kann, kann auch die Garbage Collection nicht implementiert werden. Relativ gesehen ist das Verhalten der Speicherbereinigung in diesem Bereich relativ selten, aber es ist nicht so, dass die Daten in den Methodenbereich eingegeben werden, da "permanent" als Name der permanenten Generierung vorhanden ist. Das Ziel der Speicherwiederherstellung in diesem Bereich besteht hauptsächlich in der Wiederherstellung konstanter Pools und dem Entladen von Typen. Im Allgemeinen ist die "Erreichung" der Wiederherstellung in diesem Bereich schwer zu erfüllen, insbesondere die Art des Entladens. Recycling ist in der Tat notwendig.

  Gemäß der Java Virtual Machine-Spezifikation wird eine OutOfMemoryError-Ausnahme ausgelöst, wenn der Methodenbereich die Speicherzuweisungsanforderungen nicht erfüllen kann.

Programmzähler (Programmzählerregister)

  Der Programmzähler (Programmzählerregister) ist ein kleiner Speicherplatz, und seine Funktion kann als Zeilennummernanzeige des vom aktuellen Thread ausgeführten Bytecodes angesehen werden. In dem konzeptionellen Modell der virtuellen Maschine (nur das konzeptionelle Modell können verschiedene virtuelle Maschinen auf effizientere Weise implementiert werden) ändert der Bytecode-Interpreter den Wert dieses Zählers, um den nächsten auszuführenden auszuwählen Bytecode-Anweisungen, Verzweigung, Schleife, Sprung, Ausnahmebehandlung, Thread-Wiederherstellung und andere grundlegende Funktionen müssen sich alle auf diesen Zähler verlassen, um abgeschlossen zu werden.

  Da das Multithreading der virtuellen Java-Maschine durch Thread-Switching und Zuweisung der Prozessorausführungszeit implementiert wird, führt ein Prozessor (für einen Multi-Core-Prozessor einen Core) zu einem bestimmten Zeitpunkt nur einen Thread aus Anleitung. Um die korrekte Ausführungsposition nach dem Threadwechsel wiederherzustellen, muss jeder Thread über einen unabhängigen Programmzähler verfügen. Die Zähler zwischen den einzelnen Threads beeinflussen sich nicht gegenseitig und werden unabhängig voneinander gespeichert. Wir nennen diese Art von Speicherbereich "Thread privat" "Erinnerung.

  Wenn der Thread eine Java-Methode ausführt, zeichnet dieser Zähler die Adresse des Bytecode-Befehls der virtuellen Maschine auf, der ausgeführt wird. Wenn die Natvie-Methode ausgeführt wird, ist der Zählerwert leer.

  Dieser Speicherbereich ist der einzige, der keinen OutOfMemoryError in der Java Virtual Machine-Spezifikation angibt.

Java Virtual Machine Stack (JVM-Stapel)

  Wie der Programmzähler ist auch der Java Virtual Machine Stack (Java Virtual Machine Stacks) für den Thread privat, und sein Lebenszyklus entspricht dem des Threads. Der Stapel der virtuellen Maschine beschreibt das Speichermodell der Ausführung von Java-Methoden: Wenn jede Methode ausgeführt wird, wird gleichzeitig ein Stapelrahmen (Stapelrahmen) zum Speichern der lokalen Variablentabelle, des Operationsstapels, der dynamischen Verknüpfung, des Methodenexits und anderer Informationen erstellt. Jede Methode wird aufgerufen, bis die Ausführung abgeschlossen ist. Dies entspricht einem Stapelrahmen vom Stapel zum Stapel im Stapel der virtuellen Maschine.

  In der lokalen Variablentabelle werden verschiedene grundlegende Datentypen (Boolescher Wert, Byte, Zeichen, Short, Int, Float, Long, Double) und Objektreferenzen (Referenztyp, die nicht dem Objekt selbst entsprechen, gemäß verschiedenen virtuellen Maschinen gespeichert Implementierung kann es ein Referenzzeiger auf die Startadresse des Objekts sein, es kann auch auf ein Handle zeigen, das das Objekt oder einen anderen Ort darstellt, der sich auf das Objekt bezieht) und den Typ returnAddress (der auf die Adresse eines Bytecode-Befehls zeigt).

  Unter diesen belegen die 64-Bit-langen und doppelten Datentypen 2 lokale variable Räume (Slot), und die verbleibenden Datentypen belegen nur 1 Slot. Der für die lokale Variablentabelle erforderliche Speicherplatz wird während der Kompilierung zugewiesen. Bei der Eingabe einer Methode wird vollständig festgelegt, wie viel lokaler Variablenspeicher diese Methode im Frame zuweisen muss, und die Größe der lokalen Variablentabelle wird während der Ausführung der Methode nicht geändert.

  In der Java Virtual Machine-Spezifikation sind zwei Ausnahmebedingungen für diesen Bereich angegeben: Wenn die vom Thread angeforderte Stapeltiefe größer als die von der virtuellen Maschine zugelassene Tiefe ist, wird eine StackOverflowError-Ausnahme ausgelöst. Wenn der Stapel virtueller Maschinen dynamisch erweitert werden kann (die meisten aktuellen virtuellen Java-Maschinen können dynamisch erweitert werden, die Java-Spezifikation für virtuelle Maschinen jedoch auch einen Stapel virtueller Maschinen fester Länge zulässt), wird er ausgelöst, wenn beim Erweitern nicht genügend Speicher angewendet werden kann. OutOfMemoryError-Ausnahme.

Native Method Stacks

  Native Method Stacks (Native Method Stacks) und Stacks für virtuelle Maschinen spielen eine sehr ähnliche Rolle. Der Unterschied besteht darin, dass der Stack für virtuelle Maschinen Java-Methoden (dh Bytecode) für die virtuelle Maschine ausführt, während der Stack für lokale Methoden vorgesehen ist Native Method Service, der von der virtuellen Maschine verwendet wird. Die Sprache, Verwendung und Datenstruktur der Methoden im lokalen Methodenstapel sind in der Spezifikation der virtuellen Maschine nicht obligatorisch, sodass die spezifische virtuelle Maschine sie frei implementieren kann. Einige virtuelle Maschinen (wie die virtuelle Sun HotSpot-Maschine) kombinieren den lokalen Methodenstapel und den virtuellen Maschinenstapel direkt in einem. Wie beim Stapel der virtuellen Maschine werden die Ausnahmen StackOverflowError und OutOfMemoryError im Bereich des lokalen Methodenstapels ausgelöst.

Konstanter Laufzeitpool

  Der Konstantenpool ist Teil des Methodenbereichs. Neben der Klassenversion, den Feldern, Methoden, Schnittstellen und anderen Beschreibungsinformationen in der Klassendatei gibt es auch einen Konstantenpool, in dem verschiedene vom Compiler generierte Literale und Symbolreferenzen gespeichert werden. Dieser Teil des Inhalts wird nach dem Laden der Klasse im Laufzeitkonstantenpool des Methodenbereichs gespeichert.

  Ein wichtiges Merkmal des Laufzeitkonstantenpools ist seine dynamische Natur. In der Java-Sprache müssen Konstanten nicht nur zur Kompilierungszeit generiert werden, dh der Inhalt des Konstantenpools in der Klassendatei ist nicht voreingestellt, um in den Laufzeitkonstantenpool des Methodenbereichs eingegeben zu werden. Während des Zeitraums können auch neue Konstanten in den Konstantenpool eingefügt werden. Diese Funktion wird häufig von Entwicklern als intern () -Methode der String-Klasse verwendet.

  Da der Konstantenpool zur Laufzeit Teil des Methodenbereichs ist, wird er natürlich durch den Speicher des Methodenbereichs begrenzt. Wenn der Konstantenpool keinen Speicher anwenden kann, wird eine OutOfMemoryError-Ausnahme ausgelöst.

Direkter Speicher

  Der direkte Speicher ist weder Teil des Laufzeitdatenbereichs der virtuellen Maschine noch der in der Java Virtual Machine-Spezifikation definierte Speicherbereich. Dieser Teil des Speichers wird jedoch auch häufig verwendet und kann auch OutOfMemoryError verursachen. Daher wird er hier vorgestellt.

  In JDK1.4 wurde die NIO-Klasse (New Input / Output) neu hinzugefügt und eine E / A-Methode basierend auf Channel und Buffer eingeführt. Sie kann Off-Heap-Speicher mithilfe der Native-Funktionsbibliothek direkt zuweisen und dann Ein im Java-Heap gespeichertes DirectByteBuffer-Objekt wird als Referenz auf diesen Speicher verwendet, um zu vermeiden, dass Daten im Java-Heap und im nativen Heap hin und her kopiert werden. Dies kann in einigen Szenarien die Leistung erheblich verbessern.

  Die direkte Speicherzuweisung wird nicht durch den Java-Heapspeicher begrenzt, sondern durch die Gesamtspeichergröße des Computers und den Adressraum des Prozessors. Beim Festlegen der Parameter der virtuellen Maschine legt der Serveradministrator die Parameterinformationen wie -Xms und -Xmx entsprechend dem tatsächlichen Speicher fest, ignoriert jedoch häufig den direkten Speicher, sodass die Summe jedes Speicherbereichs größer als das physische Speicherlimit ist, was zu einer OutOfMemoryError-Ausnahme während der dynamischen Erweiterung führt.

Ich denke du magst

Origin www.cnblogs.com/L-Test/p/12736914.html
Empfohlen
Rangfolge