Wo sind statische Methoden und statische Variablen in Java gespeichert?

115

Beispielsweise:

class A {
    static int i=0;
    static int j;

   static void method() {
       // static k=0; can't use static for local variables only final is permitted
       // static int L;
    }
}

Wo werden diese Variablen in Java, im Heap oder im Stack-Speicher gespeichert? Wie werden sie gespeichert?

Nav
quelle
2
Sehr nützlicher Link zum Verständnis der Garbage Collection auf der offiziellen Oracle-Website: oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/…
Arnav Joshi

Antworten:

144

Statische Methoden (tatsächlich alle Methoden) sowie statische Variablen werden im PermGenAbschnitt des Heaps gespeichert , da sie Teil der Reflexionsdaten sind (klassenbezogene Daten, nicht instanzbezogene Daten).

Update zur Verdeutlichung :

Beachten Sie, dass nur die Variablen und ihre technischen Werte (Grundelemente oder Referenzen) im PermGen-Bereich gespeichert werden.

Wenn Ihre statische Variable eine Referenz auf ein Objekt ist, wird dieses Objekt selbst in den normalen Abschnitten des Heapspeichers (junge / alte Generation oder Überlebensbereich) gespeichert. Diese Objekte (es sei denn, es handelt sich um interne Objekte wie Klassen usw.) werden nicht im PermGen-Bereich gespeichert.

Beispiel:

static int i = 1; //the value 1 is stored in the PermGen section
static Object o = new SomeObject(); //the reference(pointer/memory address) is stored in the PermGen section, the object itself is not.


Ein Wort zur Müllabfuhr:

Verlassen Sie sich nicht darauf, finalize()da die Ausführung nicht garantiert ist. Es liegt ganz bei der JVM, zu entscheiden, wann der Garbage Collector ausgeführt werden soll und was gesammelt werden soll, selbst wenn ein Objekt für die Garbage Collection geeignet ist.

Natürlich können Sie eine statische Variable auf null setzen und so den Verweis auf das Objekt auf dem Heap entfernen, aber das bedeutet nicht, dass der Garbage Collector ihn sammelt (auch wenn keine Referenzen mehr vorhanden sind).

Darüber hinaus finalize()wird es nur einmal ausgeführt, sodass Sie sicherstellen müssen, dass keine Ausnahmen ausgelöst werden oder das Sammeln des Objekts auf andere Weise verhindert wird. Wenn Sie die Finalisierung aufgrund einer Ausnahme anhalten, finalize()wird sie nicht ein zweites Mal für dasselbe Objekt aufgerufen.

Ein letzter Hinweis : Wie Code, Laufzeitdaten usw. gespeichert werden, hängt von der verwendeten JVM ab, dh HotSpot kann dies anders als JRockit tun und dies kann sogar zwischen Versionen derselben JVM unterschiedlich sein. Das Obige basiert auf HotSpot für Java 5 und 6 (diese sind im Grunde gleich), da ich zum Zeitpunkt der Beantwortung sagen würde, dass die meisten Leute diese JVMs verwendet haben. Aufgrund wesentlicher Änderungen im Speichermodell ab Java 8 gelten die obigen Aussagen möglicherweise nicht für Java 8 HotSpot - und ich habe die Änderungen von Java 7 HotSpot nicht überprüft, sodass ich denke, dass die obigen Aussagen für diese Version immer noch zutreffen. aber ich bin mir hier nicht sicher.

Thomas
quelle
1
Ahh sind Sie sicher über statische Variablen? AFAIK PermGen speichert nur die Definitionen, nicht den tatsächlichen Wert.
Amir Raminfar
2
@Amir Ich bin mir ziemlich sicher, dass die Variable selbst im Permgen-Bereich gespeichert ist. Jedes referenzierte Objekt wird höchstwahrscheinlich auf dem Heap zugewiesen. Dies könnte einige Informationen hinzufügen: stackoverflow.com/questions/3800444/…
Thomas
1
Ach ja, die Variablendefinition ist in permgen gespeichert. Aber der Wert wird auf dem Haufen sein. Ihre Antwort schlug vor, dass der Wert auch in PermGen gespeichert ist.
Amir Raminfar
1
@ Matthew, wie verstehst du meine Antwort? A sagte, dass Variablen im Permgen-Abschnitt (Grundelemente / Referenzen) gespeichert sind, nicht die Objekte, auf die sie sich beziehen. Es hängt davon ab , wie Sie einen Variablen angezeigt Wert .
Thomas
1
@Nav Nicht alle Teile des Heaps sind standardmäßig Müll, und manchmal können Klassen und damit statische Variablen nicht gesammelt werden, da Klassenlader immer noch einen Verweis darauf haben. Außerdem sollten Sie sich nicht darauf verlassen, dass der Garbage Collector ausgeführt wird, da dies völlig der JVM überlassen bleibt (es entscheidet, wann und was gesammelt werden soll. Sie können nur Hinweise wie "Ich möchte, dass Sie gc jetzt ausführen" :)). .
Thomas
25

Klassenvariablen (statische Variablen) werden als Teil der Class objectdieser Klasse zugeordneten Variablen gespeichert . Dieses Klassenobjekt kann nur von JVM erstellt und in gespeichert werden permanent generation.

Auch einige haben geantwortet, dass es in einem Nicht-Heap-Bereich gespeichert ist, der heißt Method Area.Auch diese Antwort ist nicht falsch. Es ist nur ein umstrittenes Thema, ob Permgen Area ein Teil von Heap ist oder nicht. Offensichtlich unterscheiden sich die Wahrnehmungen von Person zu Person. Meiner Meinung nach stellen wir Heap-Speicher und Permgen-Speicher in JVM-Argumenten unterschiedlich zur Verfügung. Es ist also eine gute Annahme, sie anders zu behandeln.

Eine andere Art, es zu sehen

Speicherpools werden zur Laufzeit von JVM-Speichermanagern erstellt. Der Speicherpool kann entweder zum Heap- oder zum Nicht-Heap-Speicher gehören. Ein Laufzeitkonstantenpool ist eine Laufzeitdarstellung pro Klasse oder pro Schnittstelle zur Laufzeit der Tabelle const_pool in einer Klassendatei. Jeder Laufzeitkonstantenpool wird aus dem Methodenbereich der Java Virtual Machine zugewiesen, und statische Variablen werden in diesem Methodenbereich gespeichert. Auch dieser Nicht-Heap ist nichts anderes als ein Dauerwellenbereich. Tatsächlich ist der Methodenbereich Teil des Dauerwellenbereichs. ( Referenz )

Geben Sie hier die Bildbeschreibung ein

Aniket Thakur
quelle
Ist der Methodenbereich keine Teilmenge des PermGen-Abschnitts des Speichers? Warum haben Sie den Methodenbereich als Teil des Nicht-Heap-Speichers angezeigt, wenn sie (PermGen zusammen mit dem Methoden- (Klassen-) Bereich) Teil des größeren Heap-Bereichs der JVM sind?
Kaveesh Kanwal
Lesen Sie die letzte Zeile -Also this non-heap is nothing but perm gen area.Actually Method area is part of perm gen.
Aniket Thakur
1
@AniketThakur Sie haben den Methodenbereich als Teil des Nicht-Heap-Speichers angezeigt, aber laut Oracle-Dokumenten wird hier, docs.oracle.com/javase/specs/jvms/se7/html/… , erwähnt, dass der Methodenbereich logisch Teil von ist der Haufen.
Karan
21

Vor Java 8:

Die statischen Variablen wurden im Permgenraum (auch Methodenbereich genannt) gespeichert.

PermGen Space wird auch als Methodenbereich bezeichnet

PermGen Space dient zum Speichern von 3 Dingen

  1. Daten auf Klassenebene (Metadaten)
  2. internierte Saiten
  3. statische Variablen

Ab Java 8

Die statischen Variablen werden im Heap selbst gespeichert. Ab Java 8 wurde der PermGen Space entfernt und ein neuer Space mit dem Namen MetaSpace eingeführt, der im Gegensatz zum vorherigen Permgen Space nicht mehr Teil von Heap ist. Meta-Space ist im nativen Speicher vorhanden (Speicher, den das Betriebssystem einer bestimmten Anwendung für den eigenen Gebrauch zur Verfügung stellt) und speichert jetzt nur die Klassen-Metadaten.

Die internierten Zeichenfolgen und statischen Variablen werden in den Heap selbst verschoben.

Offizielle Informationen finden Sie unter: JEP 122: Entfernen Sie den permanenten Genraum

Manish Kumar
quelle
Wenn Sie "Heap selbst" für statische Variablen> Java8 sagen, wo genau: OldGen?
Ewoks
15

Dies ist eine Frage mit einer einfachen Antwort und einer langatmigen Antwort.

Die einfache Antwort ist der Haufen. Klassen und alle Daten, die für Klassen gelten (keine Instanzdaten), werden im Abschnitt Permanente Generierung des Heaps gespeichert.

Die lange Antwort ist bereits auf Stapelüberlauf:

Es gibt eine ausführliche Beschreibung der Speicher- und Speicherbereinigung in der JVM sowie eine Antwort, die genauer darauf eingeht .

Vasiliy Sharapov
quelle
3
Sichere Sache! Vergiss nicht, diese Jungs zu verbessern, wenn du sie nützlich findest.
Vasiliy Sharapov
11

Es wird in dem Heap gespeichert, auf den die Klassendefinition verweist. Wenn Sie darüber nachdenken, hat dies nichts mit Stack zu tun, da es keinen Gültigkeitsbereich gibt.

Amir Raminfar
quelle
5

Zusätzlich zur Antwort von Thomas werden statische Variablen in einem Nicht-Heap-Bereich gespeichert, der als Methodenbereich bezeichnet wird.

Vipin
quelle
4

Da statische Variablen Variablen auf Klassenebene sind, speichern sie die " permanente Generierung " des Heapspeichers. Bitte schauen Sie in diese um weitere Informationen zu der JVM. Ich hoffe, das wird hilfreich sein

Ramesh Papaganti
quelle
3

statische Variablen werden im Heap gespeichert

CLS
quelle
7
Statische Variablen werden im PremGen-Speicher gespeichert, ihre Werte werden im Heap gespeichert.
Akash5288