web-dev-qa-db-fra.com

Comment Java (JVM) alloue-t-il une pile pour chaque thread

Une application Java démarre avec un segment de mémoire pour tous les threads. Chaque thread a sa propre pile.

Quand une application Java est démarrée, on utilise l’option JVM -Xms et -Xmx pour contrôler la taille du tas et -Xss pour contrôler la taille de la pile.

D'après ce que je comprends, le tas en cours de création devient une mémoire "gérée" de la machine virtuelle Java et tous les objets en cours de création y sont placés.

Mais comment fonctionne la création de pile? Est-ce que Java crée une pile pour chaque thread quand il est créé? Si oui, où exactement la pile est sur la mémoire? Ce n'est certainement pas dans le tas "géré".

JVM crée-t-il une pile à partir de la mémoire native ou pré-alloue-t-elle une section de la zone de mémoire gérée pour la pile? Si tel est le cas, comment la JVM sait-elle comment les threads peuvent être créés?

42
Kevin

Il y a quelques choses à propos des piles de threads que spécification Java nous dit. Entre autres:

  • Chaque thread Java de la machine virtuelle a une pile privée Java de la machine virtuelle, créée en même temps que le thread.

  • Étant donné que la pile de la machine virtuelle Java) n'est jamais manipulée directement, à l'exception des cadres Push et Pop, les cadres peuvent être alloués en tas. La mémoire d'une pile Java de la machine virtuelle pas besoin d'être contigu.

  • La spécification permet Java Les machines virtuelles ont soit une taille fixe, soit une extension et une contraction dynamiques, comme requis par le calcul.

Maintenant, si nous nous concentrons sur les implémentations JVM telles que HotSpot, nous pouvons obtenir des informations supplémentaires. Voici quelques faits que j'ai recueillis auprès de différentes sources:

  • La taille de pile minimale dans un hotSpot pour un thread semble être corrigée. C’est ce que le -Xss option est pour. (Source)

Dans Java SE 6, la valeur par défaut sur Sparc est 512k sur la machine virtuelle 32 bits et 1024k sur la machine virtuelle 64 bits. ... Vous pouvez réduire la taille de votre pile en exécutant la commande - Option Xss. ... 64 Ko est la plus petite quantité d’espace de pile autorisée par thread.

  • JRockit alloue de la mémoire séparément du tas où se trouvent les piles. (Source)

Notez que la machine virtuelle utilise plus de mémoire que le tas. Par exemple, les méthodes Java, les piles de threads et les identificateurs natifs) sont alloués en mémoire séparément du segment de mémoire, ainsi que des structures de données internes à la JVM.

  • Il existe un mappage direct entre un thread Java et un thread natif de système d'exploitation dans HotSpot. (Source) .

  • Mais la pile de threads Java dans HotSpot est gérée par logiciel), ce n'est pas une pile de threads native du système d'exploitation. (Source)

Il utilise une pile logicielle distincte pour transmettre les arguments Java, tandis que la pile C native est utilisée par VM lui-même. Un certain nombre de variables internes de la JVM, telles que le compteur de programme ou le pointeur de pile pour un thread Java) sont stockés dans des variables C, qui ne sont pas toujours conservées dans les registres du matériel. La gestion de ces structures d'interpréteur logiciel consomme une part considérable du temps d'exécution total.

  • JVM utilise également la même pile de threads Java pour les méthodes natives et les appels d'exécution JVM (par exemple, le chargement de classes). (Source) .

  • Il est intéressant de noter que même les objets alloués peuvent parfois être situés sur une pile plutôt que sur un tas pour optimiser les performances. (Source)

Les machines virtuelles Java peuvent utiliser une technique appelée analyse d'échappement, qui leur permet de savoir que certains objets restent confinés dans un seul thread pendant toute leur durée de vie, et que cette durée de vie est limitée par la durée de vie d'un cadre de pile donné. De tels objets peuvent être alloués en toute sécurité sur la pile au lieu du tas.

Et comme une image vaut mille mots, en voici une de James BloomJava memory


Maintenant, répondez à certaines de vos questions:

Comment la machine virtuelle Java sait-elle comment les threads peuvent être créés?

Ce n'est pas. Peut être facilement prouvé par contradiction en créant un nombre variable de threads. Il fait des suppositions sur le nombre maximal de threads et la taille de la pile de chaque thread. C'est pourquoi vous risquez de manquer de mémoire (ne voulant pas dire de la mémoire heap!) Si vous allouez trop de threads.

Est-ce que Java crée une pile pour chaque thread quand il est créé?

Comme mentionné précédemment, each Java de la machine virtuelle a une pile privée Java de la machine virtuelle, créée en même temps que le fil. (Source) .

Si oui, où se trouve exactement la pile dans la mémoire? Ce n'est certainement pas dans le tas "géré".

Comme indiqué ci-dessus, spécification Java permet techniquement de stocker la mémoire de pile sur le tas. Mais au moins JRockit JVM utilise une partie différente de la mémoire.

JVM crée-t-il une pile à partir de la mémoire native ou pré-alloue-t-elle une section de la zone de mémoire gérée pour la pile?

La pile est gérée par la machine virtuelle Java parce que Java spécification prescrit comment elle doit se comporter: A Java = La pile de la machine virtuelle stocke les images (§2.6). A Java La pile de la machine virtuelle est analogue à la pile d'un langage conventionnel . Les piles de méthodes natives constituent une exception. utilisé pour les méthodes native. Plus d'informations à ce sujet dans la spécification .

61
Mifeet

JVM utilise plus de mémoire que le tas. Par exemple, les méthodes Java, les piles de threads et les identificateurs natifs) sont alloués en mémoire séparément du segment de mémoire, ainsi que des structures de données internes à la JVM.

Lectures complémentaires .

Donc pour répondre à vos questions:

Est-ce que Java crée une pile pour chaque thread quand il est créé?

Oui.

Si oui, où se trouve exactement la pile dans la mémoire?

Dans la machine virtuelle Java allouée, mais pas sur le tas.

Si tel est le cas, comment la machine virtuelle Java sait-elle comment les threads peuvent être créés?

Ce n'est pas.

Vous pouvez en créer autant que vous le souhaitez jusqu’à épuisement de la mémoire de votre machine virtuelle Java et

Exception in thread "main" Java.lang.OutOfMemoryError: unable to create new native thread

MODIFIER:

Tout ce qui précède fait référence à Jrockit JVM, bien que j’ai du mal à croire que d’autres JVM seraient différentes sur des questions aussi fondamentales.

6
Daniel