Où sont stockées les méthodes statiques et les variables statiques en Java?

115

Par exemple:

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

Où ces variables seront-elles stockées en Java, en tas ou dans la mémoire de la pile? Comment sont-ils stockés?

Nav
la source
2
lien très utile pour comprendre la collecte des ordures sur le site Web officiel d'Oracle: oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/…
Arnav Joshi

Réponses:

144

Les méthodes statiques (en fait toutes les méthodes) ainsi que les variables statiques sont stockées dans la PermGensection du tas, puisqu'elles font partie des données de réflexion (données liées à la classe, non liées à l'instance).

Mise à jour pour clarification :

Notez que seules les variables et leurs valeurs techniques (primitives ou références) sont stockées dans l'espace PermGen.

Si votre variable statique est une référence à un objet, cet objet lui-même est stocké dans les sections normales du tas (génération jeune / ancienne ou espace survivant). Ces objets (sauf s'ils sont des objets internes comme des classes, etc.) ne sont pas stockés dans l'espace PermGen.

Exemple:

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.


Un mot sur le ramassage des ordures:

Ne vous fiez pasfinalize() car il n'est pas garanti de fonctionner. Il appartient totalement à la JVM de décider quand exécuter le ramasse-miettes et ce qu'il faut collecter, même si un objet est éligible pour le ramasse-miettes.

Bien sûr , vous pouvez définir une variable statique nulle et donc la retirer référence à l'objet sur le tas , mais cela ne signifie pas que le collecteur des ordures va recueillir (même s'il n'y a plus de références).

De plus, il finalize()n'est exécuté qu'une seule fois, vous devez donc vous assurer qu'il ne lève pas d'exceptions ou n'empêche pas la collecte de l'objet. Si vous arrêtez la finalisation via une exception, finalize()il ne sera pas appelé une seconde fois sur le même objet.

Une dernière remarque : la façon dont le code, les données d'exécution, etc. sont stockés dépend de la JVM utilisée, c'est-à-dire que HotSpot peut le faire différemment de JRockit et cela peut même différer entre les versions de la même JVM. Ce qui précède est basé sur HotSpot pour Java 5 et 6 (ce sont essentiellement les mêmes) car au moment de répondre, je dirais que la plupart des gens utilisaient ces JVM. En raison de changements majeurs dans le modèle de mémoire à partir de Java 8, les déclarations ci-dessus peuvent ne pas être vraies pour Java 8 HotSpot - et je n'ai pas vérifié les modifications de Java 7 HotSpot, donc je suppose que ce qui précède est toujours vrai pour cette version, mais je ne suis pas sûr ici.

Thomas
la source
1
Ahh êtes-vous sûr des variables statiques? AFAIK PermGen ne stocke que les définitions et non la valeur réelle.
Amir Raminfar
2
@Amir Je suis à peu près sûr que la variable elle-même est stockée dans l'espace permgen, tout objet référencé sera très probablement alloué sur le tas. Cela pourrait ajouter des informations: stackoverflow.com/questions/3800444/…
Thomas
1
Ah oui la définition de la variable est stockée dans permgen. Mais la valeur sera dans le tas. Votre réponse suggère que la valeur est également stockée dans PermGen.
Amir Raminfar
1
@Matthew comment comprends-tu ma réponse? A dit que les variables sont stockées dans la section permgen (primitives / références) et non les objets auxquels elles font référence. Cela dépend de la façon dont vous visualisez la valeur d' une variable .
Thomas
1
@Nav toutes les parties du tas ne sont pas collectées par défaut et parfois les classes et donc les variables statiques ne peuvent pas être collectées car les chargeurs de classe ont toujours une référence sur elles. De plus, vous ne devriez pas compter sur le ramasse-miettes pour s'exécuter car cela dépend entièrement de la JVM (il décide quand exécuter et quoi collecter, vous ne pouvez fournir que des conseils comme "Je voudrais que vous exécutiez gc maintenant" :)) .
Thomas
25

Les variables de classe (variables statiques) sont stockées dans le cadre de la Class objectclasse associée. Cet objet Class ne peut être créé que par JVM et est stocké dans permanent generation.

Certains ont également répondu qu'il était stocké dans une zone sans tas qui s'appelle Method Area.Même cette réponse n'est pas fausse. C'est juste un sujet discutable si Permgen Area fait partie du tas ou non. De toute évidence, les perceptions diffèrent d'une personne à l'autre. À mon avis, nous fournissons l'espace de tas et l'espace permgen différemment dans les arguments JVM. C'est donc une bonne hypothèse de les traiter différemment.

Une autre façon de le voir

Les pools de mémoire sont créés par les gestionnaires de mémoire JVM pendant l'exécution. Le pool de mémoire peut appartenir à une mémoire de tas ou non. Un pool de constantes d'exécution est une représentation d'exécution par classe ou par interface de la table constant_pool dans un fichier de classe. Chaque pool de constantes d'exécution est alloué à partir de la zone de méthodes de la machine virtuelle Java et les variables statiques sont stockées dans cette zone de méthodes. De plus, ce non-tas n'est rien d'autre que la zone de génération permanente.En fait, la zone de méthode fait partie de la génération permanente. ( Référence )

entrez la description de l'image ici

Aniket Thakur
la source
La zone de méthode n'est-elle pas un sous-ensemble de la section PermGen de la mémoire? Pourquoi avez-vous montré la zone de méthode dans le cadre de la mémoire sans tas alors que, je pense, elles (PermGen avec la zone de méthode (classe)) font partie de la plus grande zone de tas de la JVM?
Kaveesh Kanwal
Lire la dernière ligne -Also this non-heap is nothing but perm gen area.Actually Method area is part of perm gen.
Aniket Thakur
1
@AniketThakur vous avez montré la zone de méthode dans le cadre de la mémoire non-tas mais selon la documentation d'Oracle, ici, docs.oracle.com/javase/specs/jvms/se7/html/... , il est mentionné que la zone de méthode fait logiquement partie de le tas.
Karan
21

Avant Java 8:

Les variables statiques ont été stockées dans l'espace permgen (également appelé zone de méthode).

PermGen Space est également connu sous le nom de zone de méthode

PermGen Space utilisé pour stocker 3 choses

  1. Données au niveau de la classe (méta-données)
  2. chaînes internées
  3. variables statiques

À partir de Java 8

Les variables statiques sont stockées dans le tas lui-même. À partir de Java 8, l'espace PermGen a été supprimé et un nouvel espace nommé MetaSpace est introduit, qui ne fait plus partie de Heap contrairement à l'ancien espace Permgen. Meta-Space est présent sur la mémoire native (mémoire fournie par le système d'exploitation à une application particulière pour son propre usage) et il ne stocke désormais que les méta-données de classe.

Les chaînes internes et les variables statiques sont déplacées dans le tas lui-même.

Pour des informations officielles, reportez-vous à: JEP 122: Supprimez l'espace de génération permanente

Manish Kumar
la source
quand vous dites "tas lui-même" pour les variables statiques> Java8, où exactement: OldGen?
Ewoks
15

C'est une question avec une réponse simple et une réponse longue et longue.

La réponse simple est le tas. Les classes et toutes les données s'appliquant aux classes (pas les données d'instance) sont stockées dans la section Génération permanente du tas.

La réponse longue est déjà sur le débordement de pile:

Il existe une description détaillée de la mémoire et du ramasse-miettes dans la JVM ainsi qu'une réponse qui en parle de manière plus concise .

Vasiliy Sharapov
la source
3
Chose sûre! N'oubliez pas de voter pour ces gars si vous les trouvez utiles.
Vasiliy Sharapov
11

Il est stocké dans le tas référencé par la définition de classe. Si vous y réfléchissez, cela n'a rien à voir avec stack car il n'y a pas de portée.

Amir Raminfar
la source
5

En plus de la réponse de Thomas, les variables statiques sont stockées dans une zone sans tas qui est appelée Zone de méthode.

Vipin
la source
4

Comme les variables statiques sont des variables au niveau de la classe, elles stockeront la " génération permanente " de la mémoire du tas. Veuillez regarder cela pour plus de détails sur JVM. En espérant que cela vous sera utile

Ramesh Papaganti
la source
3

les variables statiques sont stockées dans le tas

CLS
la source
7
Les variables statiques sont stockées dans l'espace PremGen en mémoire, leurs valeurs sont stockées dans Heap.
Akash5288