Maison >Java >javaDidacticiel >Explication graphique détaillée des connaissances liées à la machine virtuelle JAVA - Modèle de mémoire JVM
Récemment, je lisais un livre Java très classique : "Compréhension approfondie de la machine virtuelle Java, deuxième édition". Je l'ai lu il y a quelques années, mais à cette époque, je ne le connaissais pas, alors je l'ai lu. J'étais confus et confus, alors j'ai arrêté de le lire. Avec le recul, je trouve qu'il est effectivement bien écrit, et je peux comprendre de nombreux points de connaissances. Il est également très approfondi et a beaucoup gagné. Plus tard, je prévois d'écrire une série d'articles basés sur le contenu de ce livre pour apprendre et revoir en profondeur les connaissances liées à la machine virtuelle Java.
Après avoir déménagé le week-end dernier, le haut débit à la maison n'a pas été réparé. Je l'ai signalé N fois au service client télécom et j'ai finalement pris rendez-vous avec un technicien pour migrer le haut débit demain matin. Cela peut mettre fin au douloureux. jours sans Internet pendant plus d'une semaine. J'ai été occupé avec diverses choses pendant cette période. Je n'ai pas mis à jour mon blog depuis une semaine. L'état et la passion avant d'arrêter d'écrire vont progressivement disparaître. Je me sens toujours paniqué. ! Profitez du week-end de demain pour enregistrer une partie du contenu d'apprentissage de cette semaine sur l'ordinateur de l'entreprise.
Le modèle de mémoire JVM est en fait assez simple Voici deux points de connaissances :
1. tas Java, pile Java (c'est-à-dire pile de machines virtuelles), pile de méthodes locales, zone de méthodes et compteur de programme.
2. Partager : La zone de méthode et la zone de tas sont partagées par les threads, et la pile de machine virtuelle, la pile de méthodes locale et le compteur de programme sont privés de thread, également appelés thread-. isolé. Chaque zone stocke un contenu différent. Ces deux points de connaissances doivent être gardés à l’esprit car ils constituent la base de la maîtrise du modèle de mémoire JVM.
2. Compteur de programme Le compteur de programme dans la JVM est une petite zone mémoire, mais cette zone mémoire est assez intéressante. Il existe 3 fonctionnalités principales :1. Contenu de stockage : Pour les méthodes Java ordinaires (c'est-à-dire les méthodes non modifiées avec le mot-clé natif), l'adresse de l'instruction en cours lors de l'exécution est stockée. . Pour la méthode native, il est vide (non défini). Pourquoi ? Car lors de l'appel de la méthode locale, l'adresse mémoire de la machine virtuelle JVM peut avoir été dépassée.
2. Discussion privée : Pourquoi le compteur du programme est-il privé pour la discussion ? C'est facile à comprendre en fonction du contenu du stockage. S'il est partagé par les threads, lorsque plusieurs threads sont en cours d'exécution, ils ne sauront pas quelle adresse le thread actuel exécute. Certains threads sont rapides et d'autres sont lents. entrez après l'avoir exécuté. Ensuite, lorsque le thread lent revient de l'exécution et constate que son adresse a changé, ne serait-ce pas compliqué ?
3. C'est la seule zone de la JVM qui ne signale pas de débordement de mémoire (OutOfMemoryError).
3. Pile de machines virtuelles La pile de machines virtuelles stocke principalement les cadres de pile. Chaque cadre de pile stocke les tables de variables locales, les piles d'opérandes et les liens dynamiques et les informations d'exportation de méthodes, etc. . La table des variables locales stocke certaines variables locales définies dans la méthode, les références d'objet, les paramètres et les adresses de retour de méthode, etc. L'espace occupé par la table des variables locales peut être déterminé au moment de la compilation. Lorsque la méthode est en cours d'exécution, la taille de l'espace de la table des variables locales ne sera pas modifiée. Ceci est facile à comprendre lorsqu'il est combiné avec le contenu stocké dans la table des variables locales. . La pile d'opérandes peut être comprise comme le chargement et le déchargement des données de l'opération en cours. Pour les types longs et doubles de 64 bits, chaque opérande occupe 2 mots de large (emplacement), et les autres types d'opérandes occupent un mot de large (emplacement). Un cadre de pile est créé lorsque chaque méthode est appelée, et le processus d'exécution correspond au processus par lequel un cadre de pile est poussé dans la pile de la machine virtuelle et retiré de la pile. Concernant le contenu des stack frames, vous pouvez vous référer à un blog écrit par un internaute : https://blog.csdn.net/xtayfjp..., qui est très bon et détaillé. Voici une photo du cadre de la pile pour que ce soit clair en un coup d'œil. Il existe deux situations concernant le débordement de mémoire de la pile de la machine virtuelle : 1. La profondeur de pile demandée par le thread dépasse la profondeur autorisée par la machine virtuelle, et un message d'erreur sera généré StackOverflowError, donc lorsque nous voyons cette exception dans le code, nous devrions penser qu'il peut y avoir un problème avec la pile de la machine virtuelle. 2. Si la pile de machines virtuelles peut être étendue dynamiquement (la plupart des JVM actuelles peuvent être étendues dynamiquement, mais la JVM autorise également des piles de machines virtuelles de longueur fixe), lorsqu'une mémoire suffisante ne peut pas être demandée pendant l'expansion, elle le sera. throw Une exception OutOfMemoryError se produit. 4. Pile de méthodes locales Ce point de connaissance est relativement simple. Les fonctions de la pile de méthodes locales et de la pile de machines virtuelles sont similaires, mais elles ne servent que lorsque la JVM appelle la méthode native. , et la JVM Le langage utilisé par les méthodes natives (par exemple, si Java appelle des fonctions implémentées en langage C, il doit définir des méthodes natives pour les implémenter), les méthodes d'utilisation et les structures de données ne sont pas obligatoires, donc différentes machines virtuelles peuvent implémenter eux librement. De plus, la machine virtuelle HotSpot combine directement la pile de méthodes locales et la pile de machines virtuelles en une seule. Semblable à la pile de machines virtuelles, la pile de méthodes locales lancera également StackOverflowError et OutOfMemoryError.La zone méthode est une zone relativement importante. La spécification de la machine virtuelle Java décrit la zone méthode comme une partie logique du tas, mais afin de correspondre au Heap (zone du tas). ), on l'appelle également Non-Heap (zone non-heap). Les variables statiques, les constantes (y compris les constantes d'exécution), les informations de chargement de classe et le code compilé Java sont principalement stockés. Cette partie de l'espace n'a pas besoin d'être continue. Vous pouvez choisir une taille fixe ou extensible. Habituellement, il n'y a pas de GC dans cette partie car GC ne recycle que les variables statiques, les constantes et les informations de chargement de classe. L'effet de recyclage de ces objets est généralement insatisfaisant. . Vous pouvez donc choisir de ne pas implémenter le garbage collection. Cette zone est aussi appelée génération persistante. Lorsque cette zone de mémoire est insuffisante, une exception OutOfMemoryError sera également signalée.
La zone de tas Java est la zone la plus volumineuse de la mémoire JVM, car toutes les instances d'objets et les objets de tableau sont stockés ici. Cette zone est partagée par les threads et sera créée au démarrage de la JVM. Pensez-y, si un espace aussi grand est privé aux threads, la mémoire ne devrait-elle pas exploser ? Selon la spécification de la machine virtuelle Java, le contenu de la zone de tas peut être physiquement discontinu, tant qu'il est logiquement continu, une fois implémenté, il peut être de taille fixe ou extensible, et il est généralement extensible. -Xms et -Xmx sont utilisés pour ajuster la taille du tas. La zone du tas Java est divisée en nouvelle génération et ancienne génération selon différents cycles de vie. La nouvelle génération peut être subdivisée en zones Eden et Survivor, et Survivor peut être subdivisé en Survivor1 et Survivor2. Ces deux-là n'utilisent généralement que l'une d'elles, et l'autre est utilisée pour conserver les objets survivants pendant le GC. La plupart des nouveaux objets sont stockés dans la zone Eden. S'il s'agit d'un objet volumineux, tel qu'un grand tableau ou un objet List, vous pouvez utiliser le paramètre JVM -XX:PretenureSizeThreshold pour stocker directement les objets dépassant la taille spécifiée dans l'ancienne génération. Il convient de noter que lors de l'écriture d'un programme, vous devez essayer d'éviter que les gros objets qui vivent et meurent n'entrent dans l'ancienne génération, car le coût du GC dans l'ancienne génération est supérieur à celui de la jeune génération. Le rapport de taille par défaut d'Eden et Survivor est de 8:1:1, et l'algorithme GC par défaut pour la nouvelle génération est l'algorithme de réplication. L'algorithme GC par défaut pour l'ancienne génération est le classement par marquage. Ces deux algorithmes GC seront expliqués dans le prochain blog.
Lorsqu'il n'y a pas assez de mémoire dans le tas, une exception OutOfMemoryError sera levée. Concernant le modèle de mémoire de la zone de tas, vous pouvez vous référer aux images suivantes :
Articles associés :
Présentation détaillée de la machine virtuelle Java
Explication détaillée du principe de fonctionnement de la machine virtuelle Java (images et textes)
Vidéos associées :
Black Horse Tutoriel vidéo de compréhension approfondie de Python de 8 jours dans Cloud Classroom
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!