Dove sono memorizzati i metodi statici e le variabili statiche in Java?


115

Per esempio:

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;
    }
}

Dove verranno archiviate queste variabili in Java, nell'heap o nella memoria dello stack? Come vengono conservati?


2
Link molto utile per comprendere la Garbage Collection sul sito ufficiale di Oracle: oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/…
Arnav Joshi

Risposte:


144

I metodi statici (di fatto tutti i metodi) e le variabili statiche sono memorizzati nella PermGensezione dell'heap, poiché fanno parte dei dati di riflessione (dati relativi alla classe, non relativi all'istanza).

Aggiornamento per chiarimenti :

Notare che solo le variabili ei loro valori tecnici (primitive o riferimenti) sono archiviati nello spazio PermGen.

Se la tua variabile statica è un riferimento a un oggetto, l'oggetto stesso viene memorizzato nelle sezioni normali dell'heap (giovane / vecchia generazione o spazio dei sopravvissuti). Questi oggetti (a meno che non siano oggetti interni come classi ecc.) Non sono memorizzati nello spazio PermGen.

Esempio:

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.


Una parola sulla raccolta dei rifiuti:

Non fare affidamento finalize()perché non è garantito che funzioni. Spetta totalmente alla JVM decidere quando eseguire il garbage collector e cosa raccogliere, anche se un oggetto è idoneo per la garbage collection.

Ovviamente puoi impostare una variabile statica su null e quindi rimuovere il riferimento all'oggetto sull'heap, ma ciò non significa che il garbage collector lo raccoglierà (anche se non ci sono più riferimenti).

Inoltre finalize()viene eseguito solo una volta, quindi devi assicurarti che non generi eccezioni o altrimenti impedire la raccolta dell'oggetto. Se interrompi la finalizzazione a causa di qualche eccezione, finalize()non verrà richiamato sullo stesso oggetto una seconda volta.

Una nota finale : il modo in cui il codice, i dati di runtime ecc. Vengono memorizzati dipende dalla JVM che viene utilizzata, ad esempio HotSpot potrebbe farlo in modo diverso da JRockit e questo potrebbe anche differire tra le versioni della stessa JVM. Quanto sopra è basato su HotSpot per Java 5 e 6 (quelli sono fondamentalmente gli stessi) poiché al momento della risposta direi che la maggior parte delle persone ha utilizzato quelle JVM. A causa di importanti cambiamenti nel modello di memoria a partire da Java 8, le dichiarazioni sopra potrebbero non essere vere per Java 8 HotSpot - e non ho controllato le modifiche di Java 7 HotSpot, quindi immagino che quanto sopra sia ancora vero per quella versione, ma non sono sicuro qui.


1
Ahh sei sicuro delle variabili statiche? Per quanto ne so PermGen memorizza solo le definizioni, non il valore effettivo.
Amir Raminfar

2
@Amir Sono abbastanza sicuro che la variabile stessa sia memorizzata nello spazio permgen, qualsiasi oggetto a cui si fa riferimento sarà molto probabilmente allocato nell'heap. Questo potrebbe aggiungere alcune informazioni: stackoverflow.com/questions/3800444/…
Thomas,

1
Ah sì, la definizione della variabile è memorizzata in permgen. Ma il valore sarà nell'heap. La tua risposta ha suggerito che il valore è memorizzato anche in PermGen.
Amir Raminfar

1
@ Matteo come interpreti la mia risposta? A detto che le variabili sono memorizzate nella sezione permgen (primitive / riferimenti) non gli oggetti a cui si riferiscono. Dipende da come si visualizza un valore di variabili .
Thomas,

1
@Nav non tutte le parti dell'heap vengono raccolte in modo indesiderato per impostazione predefinita e talvolta le classi e quindi le variabili statiche non possono essere raccolte poiché i caricatori di classi hanno ancora un riferimento su di esse. Inoltre non dovresti fare affidamento sul garbage collector per essere eseguito poiché dipende totalmente dalla JVM (decide quando eseguire e cosa raccogliere, puoi solo fornire suggerimenti come "Vorrei che eseguissi gc ora" :)) .
Thomas,

25

Le variabili di classe (variabili statiche) vengono memorizzate come parte Class objectdell'associato a quella classe. Questo oggetto Class può essere creato solo da JVM ed è archiviato in permanent generation.

Inoltre alcuni hanno risposto che è memorizzato in un'area non heap che si chiama Method Area.Anche questa risposta non è sbagliata. È solo un argomento discutibile se Permgen Area fa parte o meno. Ovviamente le percezioni differiscono da persona a persona. A mio parere, forniamo lo spazio heap e lo spazio permgen in modo diverso negli argomenti JVM. Quindi è un buon presupposto trattarli in modo diverso.

Un altro modo per vederlo

I pool di memoria vengono creati dai gestori di memoria JVM durante il runtime. Il pool di memoria può appartenere alla memoria heap o non heap. Un pool di costanti di runtime è una rappresentazione di runtime per classe o per interfaccia della tabella constant_pool in un file di classe. Ciascun pool di costanti di runtime viene allocato dall'area del metodo della Java virtual machine e le variabili statiche vengono memorizzate in questa area del metodo. Anche questo non-heap non è altro che area perm gen. In realtà l'area Method fa parte di perm gen. ( Riferimento )

inserisci qui la descrizione dell'immagine


l'area del metodo non è un sottoinsieme della sezione PermGen della memoria? Perché hai mostrato l'area del metodo come parte della memoria non heap quando, penso, loro (PermGen insieme all'area del metodo (classe)) fanno parte dell'area di heap più ampia della JVM?
Kaveesh Kanwal

Leggi l'ultima riga -Also this non-heap is nothing but perm gen area.Actually Method area is part of perm gen.
Aniket Thakur

1
@AniketThakur hai mostrato l'area del metodo come parte della memoria non heap ma secondo la documentazione di Oracle, qui, docs.oracle.com/javase/specs/jvms/se7/html/… , si dice che l'area del metodo fa parte logicamente il mucchio.
Karan

21

Prima di Java 8:

Le variabili statiche sono state memorizzate nello spazio permgen (chiamato anche area del metodo).

PermGen Space è anche noto come Method Area

PermGen Space utilizzato per memorizzare 3 cose

  1. Dati a livello di classe (metadati)
  2. stringhe interne
  3. variabili statiche

Da Java 8 in poi

Le variabili statiche sono memorizzate nell'Heap stesso. Da Java 8 in poi è stato rimosso PermGen Space e viene introdotto un nuovo spazio denominato MetaSpace che non fa più parte di Heap a differenza del precedente Permgen Space. Meta-Space è presente sulla memoria nativa (memoria fornita dal sistema operativo a una particolare applicazione per il proprio utilizzo) e ora memorizza solo i metadati della classe.

Le stringhe interne e le variabili statiche vengono spostate nell'heap stesso.

Per informazioni ufficiali fare riferimento a: JEP 122: Remove the Permanent Gen Space


quando dici "heap stesso" per variabili statiche> Java8, dove esattamente: OldGen?
Ewoks

15

Questa è una domanda con una risposta semplice e una risposta prolissa.

La risposta semplice è il mucchio. Le classi e tutti i dati che si applicano alle classi (non i dati dell'istanza) vengono archiviati nella sezione Generazione permanente dell'heap.

La risposta lunga è già in overflow dello stack:

C'è una descrizione completa della memoria e della garbage collection nella JVM , nonché una risposta che ne parla in modo più conciso .


3
Cosa certa! Non dimenticare di dare un voto positivo a quei ragazzi se li trovi utili.
Vasiliy Sharapov

11

Viene archiviato nell'heap a cui fa riferimento la definizione della classe. Se ci pensi, non ha nulla a che fare con lo stack perché non c'è ambito.


5

Oltre alla risposta di Thomas, le variabili statiche vengono memorizzate in un'area non heap chiamata Area del metodo.


4

Poiché le variabili statiche sono variabili a livello di classe, memorizzano la " generazione permanente " di memoria heap. Si prega di esaminare questo per maggiori dettagli su JVM. Sperando che questo possa essere utile


3

le variabili statiche vengono memorizzate nell'heap


7
Le variabili statiche sono archiviate nello spazio PremGen in memoria, i loro valori sono archiviati in Heap.
Akash5288
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.