Der Haufen und Stapel -Java in Java unterteilt den Speicher in zwei Typen: Der eine ist Stapelspeicher und der andere ist Heap -Speicher.
Einige grundlegende Arten von Variablen, die in Funktionen und Referenzvariablen von Objekten definiert sind, werden im Stapelspeicher der Funktion zugewiesen. Wenn eine Variable in einem Codeblock definiert wird, weist Java Speicherplatz für die Variable im Stapel zu. Wenn der Umfang der Variablen den Umfang der Variablen überschreitet, löst Java den für die Variablen zugewiesenen Speicherraum automatisch frei, und der Speicherraum kann sofort separat verwendet werden.
Der Heap -Speicher wird verwendet, um Objekte und Arrays zu speichern, die von New erstellt wurden. Der im Haufen zugewiesene Speicher wird vom automatischen Müllsammler der Java Virtual Machine verwaltet. Nachdem ein Array oder Objekt im Haufen generiert wurde, kann eine spezielle Variable im Stapel definiert werden. Der Wert dieser Variablen entspricht der ersten Adresse des Arrays oder Objekts im Heap -Speicher. Diese spezielle Variable im Stapel wird zu einer Referenzvariablen für das Array oder Objekt. In Zukunft können Sie die Referenzvariable im Stack -Speicher im Programm verwenden, um auf das Array oder Objekt im Haufen zuzugreifen. Die Referenzvariable entspricht einem Alias- oder Code -Namen für das Array oder Objekt.
Referenzvariablen sind gewöhnliche Variablen. Bei der Definition wird der Speicher auf dem Stapel zugewiesen. Referenzvariablen werden außerhalb des Umfangs freigegeben, wenn das Programm ausgeführt wird. Das Array & Objekt selbst wird im Haufen zugewiesen. Auch wenn das Programm außerhalb des Codeblocks läuft, in dem die Anweisungen, mit denen neu das Array und das Objekt generiert werden, befinden, wird der vom Array und des Objekt selbst besetzte Heap -Speicher nicht freigegeben. Das Array und das Objekt werden nur zu Müll, wenn keine Referenzvariable darauf hinweist und nicht mehr verwendet werden kann, sondern dennoch den Speicher belegt und vom Müllsammler zu einer unsicheren Zeit freigesetzt wird. Dies ist auch der Hauptgrund, warum Java mehr Erinnerung annimmt. Tatsächlich verweisen Variablen im Stapel auf Variablen im Heap -Speicher, der Zeiger in Java ist!
Haufen und Stapel in Java
Java unterteilt den Speicher in zwei Typen: Einer ist Stapelspeicher und der andere ist Heap -Speicher.
1. Stack und Heap sind beide Orte, die von Java verwendet werden, um Daten in RAM zu speichern. Im Gegensatz zu C ++ verwaltet Java automatisch Stapel und Haufen, und Programmierer können keine Stapel oder Haufen direkt einrichten.
2. Der Vorteil des Stapels besteht darin, dass die Zugangsgeschwindigkeit schneller als der Haufen ist, nur die Register, die sich direkt in der CPU befinden. Der Nachteil ist jedoch, dass die Datengröße und die Lebensdauer im Stapel deterministisch sein müssen und keine Flexibilität haben. Darüber hinaus können Stapeldaten gemeinsam genutzt werden. Der Vorteil des Haufens besteht darin, dass er die Speichergröße dynamisch zuweisen kann und die Lebensdauer dem Compiler nicht im Voraus mitgeteilt werden muss. Der Müllsammler von Java sammelt automatisch die nicht mehr verwendeten Daten. Der Nachteil ist jedoch, dass der Speicher zur Laufzeit dynamisch zugewiesen werden muss, die Zugriffsgeschwindigkeit langsamer.
3.. In Java gibt es zwei Arten von Daten.
Eines sind die Grundtypen (primitive Typen), es gibt 8 Typen, nämlich int, kurz, lang, byte, float, doppelt, boolean, char (Notiz,
Es gibt keine grundlegende Stringart). Diese Art von Definition wird durch eine Form wie int a = 3 definiert; lang B = 255L; und wird als automatische Variable bezeichnet. Es ist erwähnenswert, dass die automatische Variable wörtliche Werte enthält, nicht Instanzen der Klasse, dh keine Verweise auf die Klasse, und es gibt hier keine Klasse. Zum Beispiel int a = 3; Hier ist A eine Referenz, die auf den Int -Typ zeigt,
Zeigen Sie auf den wörtlichen Wert von 3. Aufgrund der Größe dieser wörtlichen Werte kann die Lebensdauer dieser wörtlichen Werte bekannt sein (diese wörtlichen Werte werden in einem Programmblock fest definiert, und nachdem der Programmblock beendet ist, verschwindet der Feldwert).
Um Geschwindigkeit zu verfolgen, existiert es im Stapel.
Darüber hinaus ist eine sehr wichtige Spezialmerkmal des Stacks, dass die Daten im Stapel gemeinsam genutzt werden können. Angenommen, wir definieren gleichzeitig:
int a = 3;
int b = 3;
Der Compiler verarbeitet zuerst int a = 3; Zuerst wird ein Verweis auf die Variable A im Stapel erzeugt und dann herausfinden, ob es eine Adresse mit einem wörtlichen Wert von 3 gibt. Wenn sie nicht gefunden wird, wird eine Adresse mit dem wörtlichen Wert von 3 geöffnet und dann auf die Adresse von 3 an die Adresse 3 verarbeiten. Int B = 3; Nachdem die Referenzvariable von B erstellt wurde, wird B im Stapel bereits ein wörtlicher Wert von 3 vorhanden, sondern auf diese Weise direkt auf die Adresse von 3 hingewiesen. A und B zeigen beide gleichzeitig auf 3.
Es ist besonders wichtig zu beachten, dass sich diese wörtliche Referenz von der von Klassenobjekten unterscheidet. Unter der Annahme, dass die Referenzen von zwei Klassenobjekten gleichzeitig auf ein Objekt verweisen, spiegelt die andere Objektreferenzvariable diese Änderung sofort wider. Stattdessen führt die Änderung des Wertes durch eine wörtliche Referenz nicht zu einem entsprechenden Wert, dass ein weiterer Wert geändert wird. Wie im obigen Beispiel, nachdem wir die Werte von A und B definiert haben, sei a = 4; Dann ist B nicht gleich 4 oder in einem Inneren des Compilers, wenn A = 4 angetroffen wird, wird es erneut suchen, ob im Stapel einen wörtlichen Wert von 4 vorhanden ist. Wenn nicht, öffnen Sie die Adresse erneut, um den Wert von 4 zu speichern. Wenn es bereits vorhanden ist, zeigen Sie direkt A auf diese Adresse. Daher wirkt sich die Wertänderung A nicht auf den Wert b aus.
Ein anderer Typ sind Verpackungsklassendaten wie Ganzzahl, String, Doppel usw., die die entsprechenden grundlegenden Datentypen umwickeln. Alle diese Klassendaten sind im Haufen vorhanden. Java verwendet die neue () Anweisung, um den Compiler anzuzeigen, und erstellt nur nach Bedarf dynamisch zur Laufzeit. Daher ist er flexibler, aber der Nachteil ist, dass es mehr Zeit in Anspruch nimmt.
In Java gibt es sechs verschiedene Orte, an denen Daten gespeichert werden können:
1. Register. Dies ist der schnellste Speicherbereich, da er sich an einem anderen Ort befindet als andere Speicherbereiche - der Prozessor. Die Anzahl der Register ist jedoch äußerst begrenzt, sodass Register vom Compiler gemäß den Anforderungen zugewiesen werden. Sie können es weder direkt kontrollieren, noch können Sie Anzeichen für die Existenz des Registers im Programm spüren.
2. Stack. Das im Allgemeinen RAM ansässig, aber mit seinem "Stackzeiger" können Sie vom Prozessor unterstützt werden. Wenn sich der Stapelzeiger nach unten bewegt, wird ein neues Speicher zugewiesen. Wenn es nach oben bewegt wird, wird diese Erinnerung befreit. Dies ist eine schnelle und effiziente Möglichkeit, die Speicherung zuzuweisen, die nur den Registern an zweiter Stelle steht. Beim Erstellen eines Programms muss der Java -Compiler die genaue Größe und den Lebenszyklus aller im Stapel gespeicherten Daten kennen, da er den entsprechenden Code generieren muss, um den Stapelzeiger auf und ab zu verschieben. Diese Einschränkung begrenzt die Flexibilität des Programms. Obwohl einige JA VA -Daten auf dem Stapel gespeichert werden - insbesondere Objektreferenzen, werden Java -Objekte nicht darin gespeichert.
3. Haufen. Ein universeller Speicherpool (auch im RAM) zum Speichern von sogenannten Java-Objekten. Der Vorteil des Haufens besteht darin, dass der Compiler nicht wissen muss, wie viele Speicherbereiche aus dem Haufen zuweisen müssen, und es muss auch nicht wissen, wie lange die gespeicherten Daten auf dem Haufen dauern werden. Daher gibt es eine große Flexibilität bei der Zuordnung der Speicherung im Haufen. Wenn Sie ein Objekt erstellen müssen, müssen Sie nur eine einfache Codezeile in neuem Schreiben schreiben. Bei der Ausführung dieser Codezeile wird automatisch im Haufen gespeichert und zugewiesen. Natürlich muss der entsprechende Code für diese Flexibilität bezahlt werden. Es dauert mehr Zeit, um den Speicher mit dem Haufen zuzuweisen, als ihn mit dem Stapel zu speichern.
4. Statische Speicherung. "statisch" bedeutet hier "in einer festen Position". Statische Speicher speichert Daten, die immer existiert haben, wenn das Programm ausgeführt wird. Sie können das Schlüsselwort statisch verwenden, um festzustellen, dass ein bestimmtes Element eines Objekts statisch ist, aber das Java -Objekt selbst wird nie im statischen Speicherplatz gespeichert.
5. Ständige Speicherung. Konstante Werte werden normalerweise direkt im Programmcode gespeichert, und dies ist sicher, da sie niemals geändert werden. Manchmal ist die Konstante selbst in einem eingebetteten System von anderen Teilen getrennt, so dass es in diesem Fall optional ist, sie in das ROM zu stecken.
6. Nicht-Ram-Speicher. Wenn die Daten vollständig außerhalb des Programms überlebt, kann sie ohne Kontrolle über das Programm gelassen werden und kann existieren, wenn das Programm nicht ausgeführt wird.
In Bezug auf die Geschwindigkeit gibt es eine Beziehung wie folgt:
Registrieren Sie <Stack <Heap <Andere
"Die obige Passage wird aus" Denken in Java "extrahiert" "
Frage 1:
String str1 = "ABC"; String str2 = "ABC"; System.out.println (str1 == str2); //WAHR
Frage 2:
String str1 = new String ("ABC"); String str2 = new String ("ABC"); System.out.println (str1 == str2); // FALSCH Frage 3:
String S1 = "Ja"; String s2 = "va"; String S3 = "Java"; String S4 = S1 + S2; System.out.println (S3 == S4); // False System.out.println (S3.Equals (S4)); // True
Einige grundlegende Arten von Variablen, die in der Funktions- und Referenzvariablen des Objekts definiert sind, werden im Stapelspeicher der Funktion zugewiesen.
Wenn eine Variable in einem Codeblock definiert wird, weist Java den Speicherraum für diese Variable im Stapel zu. Wenn der Umfang der Variablen die Variable überschreitet, löst Java den für die Variablen zugewiesenen Speicherraum automatisch frei, und der Speicherplatz kann sofort separat verwendet werden.
Der Heap -Speicher wird verwendet, um Objekte und Arrays zu speichern, die von New erstellt wurden.
Der im Heap zugewiesene Speicher wird vom automatischen Müllsammler der Java Virtual Machine verwaltet.
Nachdem ein Array oder Objekt im Heap erzeugt wurde, kann im Stapel eine spezielle Variable definiert werden, so dass der Wert dieser Variablen im Stapel gleich der ersten Adresse des Arrays oder Objekts im Heap -Speicher ist, und die Variable im Stapel wird zu einer Referenzvariablen für das Array oder Objekt.
Eine Referenzvariable entspricht einem Namen, der einem Array oder Objekt gegeben wurde. Sie können die Referenzvariablen im Stapel im Programm verwenden, um auf das Array oder Objekt im Haufen zuzugreifen.
Insbesondere: Der Stapel und der Haufen sind beide Orte, die von Java verwendet werden, um Daten in RAM zu speichern. Im Gegensatz zu C ++ verwaltet Java automatisch Stapel und Haufen, und Programmierer können keine Stapel oder Haufen direkt einrichten.
Der Java Heap ist ein Laufzeitbereich, aus dem Objekte Platz zuweisen. Diese Objekte werden durch Anweisungen wie New, Newarray, Neuarray und Multianewarray festgelegt. Sie müssen nicht ausdrücklich den Programmcode veröffentlicht. Der Haufen ist für die Müllsammlung verantwortlich. Der Vorteil des Haufens besteht darin, dass er die Speichergröße dynamisch zuordnen kann und die Lebensdauer dem Compiler nicht im Voraus mitgeteilt werden muss, da er zur Laufzeit dynamisch Speicher zuteilt. Der Müllsammler von Java sammelt automatisch die nicht mehr verwendeten Daten. Der Nachteil ist jedoch, dass die Zugriffsgeschwindigkeit langsamer ist, weil er zur Laufzeit dynamisch Speicher zuordnen muss.
Der Vorteil des Stacks besteht darin, dass die Zugangsgeschwindigkeit schneller als der Haufen ist, der nur die Register an zweiter Stelle steht und die Stapeldaten gemeinsam genutzt werden können. Der Nachteil ist jedoch, dass die Datengröße und die Lebensdauer im Stapel deterministisch sein müssen und keine Flexibilität haben. Der Stapel speichert hauptsächlich einige grundlegende Arten von Variablen (, int, kurz, lang, byte, float, doppelt, boolean, char) und Objektgriffe.
Eine sehr wichtige Spezialmerkmal des Stacks ist, dass die im Stapel vorhandenen Daten gemeinsam genutzt werden können. Angenommen, wir definieren gleichzeitig:
int a = 3;
int b = 3;
Der Compiler verarbeitet zuerst int a = 3; Zuerst erstellt es eine Referenz im Stapel mit einer Variablen A und findet dann heraus, ob im Stapel einen Wert von 3 vorhanden ist. Wenn es nicht gefunden wird, speichert es 3 und verarbeiten Sie dann int B = 3; Nachdem die Referenzvariable von B erstellt wurde, da im Stapel bereits ein Wert von 3 vorhanden ist, wird B direkt auf 3 gezeigt. Auf diese Weise verweisen A und B beide gleichzeitig auf 3. Zu diesem Zeitpunkt ist, wenn a = 4 wieder eingestellt ist; Dann sucht der Compiler erneut, ob im Stapel einen Wert von 4 Wert aufweist. Wenn nicht, speichern Sie 4 und Punkt A bis 4; Wenn es bereits vorhanden ist, weisen Sie sich direkt auf diese Adresse an. Daher wirkt sich die Wertänderung A nicht auf den Wert b aus. Es ist zu beachten, dass sich diese Teile von Daten von der Freigabe von Referenzen aus zwei Objekten unterscheidet, die gleichzeitig auf ein Objekt zeigen, da in diesem Fall die Änderung von A nicht beeinflusst wird, was der Compiler für den Speicherplatz förderlich ist. Eine Objektreferenzvariable verändert den internen Status dieses Objekts und wirkt sich auf eine andere Objektreferenzvariable aus.
String sind spezielle Verpackungsdaten. Kann verwendet werden:
String str = new String ("ABC"); String str = "ABC"; Es gibt zwei Formen zu erstellen. Die erste besteht darin, New () ein neues Objekt zu erstellen, das im Haufen gespeichert wird. Jedes Mal, wenn es aufgerufen wird, wird ein neues Objekt erstellt.
Der zweite Typ besteht darin, zuerst eine variable STR zum Objekt der String -Klasse im Stapel zu erstellen und dann herauszufinden, ob im Stapel "ABC" gespeichert ist. Wenn nicht, speichern Sie "ABC" auf dem Stapel und lassen Sie String auf "ABC" zeigen. Wenn es bereits "ABC" gibt, lassen Sie STR direkt auf "ABC" verweisen.
Verwenden Sie beim Vergleichen, ob die Werte in der Klasse gleich sind, die Equals () -Methode; Wenn Sie testen, ob die Referenzen der beiden Wrapper -Klassen auf dasselbe Objekt deuten, verwenden Sie == und verwenden Sie das folgende Beispiel, um die obige Theorie zu veranschaulichen.
String str1 = "ABC"; String str2 = "ABC"; System.out.println (str1 == str2); //WAHR
Es ist ersichtlich, dass Str1 und Str2 auf dasselbe Objekt verweisen.
String str1 = new String ("ABC"); String str2 = new String ("ABC"); System.out.println (str1 == str2); // FALSCH Die neue Methode besteht darin, verschiedene Objekte zu generieren. Erzeugen nacheinander.
In der zweiten Art und Weise werden mehrere "ABC" -Schaiten erstellt, und es gibt nur ein Objekt im Speicher. Diese Schreibmethode ist vorteilhaft und spart Speicherplatz. Gleichzeitig kann es die Laufgeschwindigkeit des Programms bis zu einem gewissen Grad verbessern, da die JVM automatisch entscheidet, ob es erforderlich ist, ein neues Objekt basierend auf der tatsächlichen Situation der Daten im Stapel zu erstellen. Für den Code von String Str = New String ("ABC");
HINWEIS: HINWEIS: Wenn wir eine Klasse unter Verwendung eines Formats wie String Str = "ABC" definieren, halten wir es immer als selbstverständlich an, dass wir ein Objekt STR der String -Klasse erstellen. (Nicht unbedingt, denn wenn es nicht im Voraus gibt, wird es erstellt. Dies ist die Erstellung des Objekts. Wenn es bereits vorhanden ist, zeigen Sie auf das ursprüngliche Objekt)! Das Objekt wurde möglicherweise nicht erstellt! Und vielleicht nur auf ein Objekt verweisen, das zuvor erstellt wurde. Nur durch die neue () -Methode kann wir sicherstellen, dass jedes Mal ein neues Objekt erstellt wird. Aufgrund der unveränderlichen Art der String -Klasse sollten Sie in Betracht ziehen, die StringBuffer -Klasse häufig zu verändern, um die Programmeffizienz zu verbessern.