web-dev-qa-db-fra.com

allocation statique dans Java - génération de tas, pile et permanente

Ces derniers temps, j’ai beaucoup lu sur les schémas d’allocation de mémoire en Java, et j’ai eu de nombreux doutes car je lisais depuis diverses sources. J'ai rassemblé mes concepts et je vous demanderais de passer en revue tous les points et de les commenter. J'ai appris que l'allocation de mémoire est spécifique à la machine virtuelle Java. Je dois donc dire à l'avance que ma question est spécifique à Sun.

  1. Les classes (chargées par les chargeurs de classe) vont dans une zone spéciale sur le tas: la génération permanente
  2. Toutes les informations relatives à une classe telles que le nom de la classe, les tableaux d'objets associés à la classe, les objets internes utilisés par la machine virtuelle (comme Java/lang/Object) et les informations d'optimisation sont placées dans la zone de génération permanente.
  3. Toutes les variables membres statiques sont à nouveau conservées dans la zone de génération permanente.
  4. Les objets vont sur un tas différent: Jeune génération
  5. Il n'y a qu'une copie de chaque méthode par classe, que ce soit la méthode statique ou non statique. Cette copie est placée dans la zone de génération permanente. Pour les méthodes non statiques, tous les paramètres et les variables locales sont placés dans la pile - et chaque fois que cette méthode est invoquée de manière concrète, un nouveau cadre de pile lui est associé. Je ne suis pas sûr où sont stockées les variables locales d'une méthode statique. Sont-ils sur le tas de la génération permanente? Ou simplement leur référence est stockée dans la zone de génération permanente, et la copie réelle est quelque part ailleurs (Où?)
  6. Je ne sais pas non plus où le type de retour d'une méthode est stocké.
  7. Si les objets (dans la jeune génération) doivent utiliser un membre statique (dans la génération permanente), ils se voient attribuer une référence au membre statique &&, ils disposent de suffisamment d’espace mémoire pour stocker le type de résultat de la méthode, etc.

Merci d'avoir traversé ça!

110
Jaguar

Tout d’abord, comme vous devriez le constater maintenant, très peu de personnes peuvent confirmer ces réponses à partir de connaissances directes. Très peu de personnes ont travaillé sur les dernières machines virtuelles HotSpot ou les ont étudiées à la profondeur voulue. La plupart des gens ici (y compris moi-même) répondent en se basant sur des choses qu'ils ont vues écrites ailleurs ou sur ce qu'ils ont déduit. Habituellement, ce qui est écrit ici, ou dans divers articles et pages Web, est basé sur d’autres sources qui peuvent être définitives ou non. C'est souvent simplifié, inexact ou tout simplement faux.

Si vous voulez une confirmation définitive de vos réponses, vous devez absolument télécharger le code source OpenJDK ... et faites vos propres recherches en lisant et en comprenant le code source. Poser des questions sur les SO, ou parcourir des articles Web au hasard, n’est pas une technique de recherche universitaire solide.

Ayant dit cela ...

1) Les classes (chargées par les chargeurs de classe) vont dans une zone spéciale du tas: la génération permanente.

Autant que je sache, oui. ( Update : voir ci-dessous.)

2) Toutes les informations relatives à une classe telles que le nom de la classe, les tableaux d’objets associés à la classe, les objets internes utilisés par la machine virtuelle (comme Java/lang/Object) et les informations d’optimisation sont placées dans la zone de génération permanente.

Plus ou moins, oui. Je ne suis pas sûr de ce que vous entendez par certaines de ces choses. Je suppose que "les objets internes utilisés par la machine virtuelle Java (comme Java/lang/Object)" désignent des descripteurs de classe internes à la machine virtuelle Java.

3) Toutes les variables membres statiques sont à nouveau conservées dans la zone de génération permanente.

Les variables elles-mêmes oui. Ces variables (comme toutes les variables Java) contiendront des valeurs primitives ou des références d'objet. Toutefois, bien que les variables de membre statique soient dans un cadre alloué dans le segment de mémoire permanent, les objets/tableaux référencés to par ces variables peut être alloué dans any heap.

4) Les objets vont sur un tas différent: Jeune génération

Pas nécessairement. Les gros objets peut être alloués directement à la génération permanente.

5) Il n'y a qu'un seul exemplaire de chaque méthode par classe, que ce soit statique ou non statique. Cette copie est placée dans la zone de génération permanente.

En supposant que vous vous référiez au code de la méthode, alors, autant que je sache, oui. C'est peut-être un peu plus compliqué cependant. Par exemple, ce code peut exister sous forme de code unique et/ou de code natif à différents moments de la vie de la JVM.

... Pour les méthodes non statiques, tous les paramètres et les variables locales vont dans la pile - et chaque fois qu'il y a un appel concret à cette méthode, nous obtenons un nouveau cadre de pile qui lui est associé.

Oui.

... Je ne sais pas où sont stockées les variables locales d'une méthode statique. Sont-ils sur le tas de la génération permanente? Ou simplement leur référence est stockée dans la zone de génération permanente, et la copie réelle est quelque part ailleurs (Où?)

Non. Elles sont stockées dans la pile, tout comme les variables locales dans les méthodes non statiques.

6) Je ne sais pas non plus où est stocké le type de résultat d'une méthode.

Si vous voulez dire le valeur renvoyé par un appel de méthode (non vide), il est renvoyé soit sur la pile, soit dans un registre de machine. S'il est renvoyé sur la pile, cela prend 1 ou 2 mots, en fonction du type de retour.

7) Si les objets (de la jeune génération) doivent utiliser un membre statique (de la génération permanente), ils se voient attribuer une référence au membre statique &&, ils disposent de suffisamment d’espace mémoire pour stocker le type de résultat de la méthode, etc. .

C'est inexact (ou du moins, vous ne vous exprimez pas clairement).

Si une méthode accède à une variable membre statique, elle obtient soit une valeur primitive, soit un objet référence . Cela peut être affecté à une variable ou à un paramètre local (existant), à un membre statique ou non statique (existant), à un élément (existant) d'un tableau précédemment alloué ou simplement utilisé et ignoré.

  • En aucun cas nouveau le stockage ne doit être alloué pour contenir une valeur de référence ou une valeur primitive.

  • En règle générale, un mot de la mémoire est tout ce qui est nécessaire pour stocker un objet ou une référence de tableau, et une valeur primitive occupe généralement un ou deux mots, en fonction de l'architecture matérielle.

  • En aucun cas, l'appelant n'a besoin d'espace pour contenir un objet/un tableau renvoyé par une méthode. En Java, les objets et les tableaux sont toujours renvoyés à l'aide de la sémantique passe par valeur ... mais la valeur renvoyée est une référence d'objet ou de tableau.

[~ # ~] met à jour [~ # ~]

A partir de Java 8, l’espace PermGen a été remplacé par Metaspace. Pour plus d’informations, consultez les ressources suivantes:

142
Stephen C