Résumé des questions d'entretien Jvm et 300 réponses (questions d'entretien pour Jvm)

Les questions et réponses d'entretien Jvm (questions d'entretien Jvm avec réponses) ont révélé que de nombreuses questions et réponses d'entretien Jvm sur Internet n'ont pas de réponses, il a donc fallu beaucoup de temps pour les collecter, cet ensemble de questions d'entretien Jvm contient un grand nombre d'entretiens Jvm classiques questions et réponses, y compris les questions d'entretien courantes en langage Jvm, les compétences en matière d'expérience d'entretien, etc. Les nouveaux diplômés, les stagiaires et ceux qui ont travaillé dans des entreprises peuvent s'y référer pour apprendre !

Si vous ne mémorisez pas les réponses aux questions de l'entretien Jvm, vous échouerez certainement à l'entretien !

Cet ensemble de questions d'entretien Jvm est complet, j'espère qu'il sera utile à tout le monde ~
Le blogueur a compilé les questions d'entretien suivantes dans un manuel d'entretien, qui est la version PDF
1. Comprenez-vous ZGC ?
Le ramasse-miettes expérimental à faible latence ajouté dans JDK11 vise à atteindre une faible latence qui peut limiter le temps de pause à moins de 10 ms dans n'importe quelle taille de mémoire de tas sans affecter le débit autant que possible.

Sur la base de la disposition de la mémoire de région, aucune génération n'est définie et des technologies telles que les barrières de lecture, les pointeurs colorés et le mappage multiple de la mémoire sont utilisées pour réaliser un tri de marques simultané, avec une faible latence comme objectif principal.

La région de ZGC est dynamique, elle est créée et détruite dynamiquement, et sa capacité est également modifiée dynamiquement.

2. Qu'est-ce qu'un point de sécurité ?
STW ne se produit pas seulement lorsque la mémoire est récupérée. Maintenant que les programmeurs sont tellement impliqués, les chances de rencontrer plusieurs problèmes de points de sécurité sont relativement élevées.

Lorsque GC se produit, tous les threads utilisateur doivent être arrêtés avant que la récupération de place puisse être effectuée. Dans cet état, nous pouvons considérer que la JVM est sûre (sûre) et que l'état de l'ensemble du tas est stable.

S'il existe un thread qui ne peut pas entrer dans le point de sécurité avant le GC, l'ensemble de la JVM attend le thread bloqué, ce qui allonge le temps global du GC.

3. Outil commun
jps fourni par JVM :

Utilisé pour afficher le processus Java local, vous pouvez afficher plusieurs programmes Java exécutés localement et afficher leurs numéros de processus. Format de commande : jps

jinfo:

Paramètres de l'environnement d'exploitation : propriétés du système Java et paramètres de ligne de commande JVM, chemin de classe Java et autres informations. Format de commande : pid du processus jinfo

rester:

Un outil de ligne de commande pour surveiller diverses informations sur l'état de fonctionnement des machines virtuelles. Format de commande : jstat -gc 123 250 20

jstack:

Vous pouvez observer l'état d'exécution de tous les threads actuels dans la JVM et l'état actuel des threads. Format de commande : pid du processus jstack

jmap:

Observez l'utilisation de la mémoire physique de la JVM en cours d'exécution (par exemple : quels objets sont générés et leur nombre). Format de la commande : jmap [option] pid

4. Collecteur CMS (algorithme de balayage de marques multithread) Le
collecteur de balayage de marques simultanées (CMS) est un ramasse-miettes d'ancienne génération dont l'objectif principal est d'obtenir le temps de pause le plus court pour la collecte des ordures, et d'autres marques d'utilisation d'ancienne génération. L'algorithme de classement est différent, il utilise un algorithme multi-thread mark-sweep. Des pauses minimales de récupération de place peuvent améliorer l'expérience utilisateur pour les programmes hautement interactifs. Le mécanisme de travail du CMS est plus compliqué que celui des autres ramasse-miettes. L'ensemble du processus est divisé en 4 étapes :

marque initiale

Marquez simplement les objets qui peuvent être directement associés à GC Roots, qui est très rapide et qui doit encore suspendre tous les threads de travail.

marque concurrente

Le processus de suivi GC Roots fonctionne avec les threads utilisateur sans suspendre les threads de travail.

réétiqueter

Afin de corriger l'enregistrement de marquage de la partie de l'objet dont le marquage change du fait de l'exécution continue du programme utilisateur lors du marquage concurrent, il est encore nécessaire de suspendre tous les threads de travail.

purge simultanée

Effacez les objets inaccessibles de GC Roots et travaillez avec les threads utilisateur sans suspendre les threads de travail. Étant donné que le thread de récupération de place peut fonctionner en même temps que l'utilisateur pendant le processus de marquage et d'effacement simultané le plus long et le plus long, la récupération de la mémoire du collecteur CMS et du thread utilisateur sont généralement exécutées simultanément.

5. Tous les objets sont-ils attribués à la jeune génération en premier ?
Non. Lorsque la mémoire de nouvelle génération ne suffit pas, la garantie d'allocation de l'ancienne génération. Les objets volumineux sont attribués directement dans l'ancienne génération.

6. Quels sont les algorithmes GC ?
algorithme de balayage de marque

Il est divisé en phases de marquage et d'effacement.Premièrement, à partir de chaque racine GC, les objets avec des relations de référence sont marqués à leur tour, et enfin les objets qui ne sont pas marqués sont effacés.

L'efficacité d'exécution est instable. Si le tas contient un grand nombre d'objets et que la plupart d'entre eux doivent être recyclés, un grand nombre d'effacements de marques doivent être effectués, ce qui entraîne une diminution de l'efficacité à mesure que le nombre d'objets augmente.

Il existe un problème de fragmentation de l'espace mémoire, qui générera un grand nombre de fragments de mémoire discontinus, ce qui déclenchera facilement le Full GC lorsque de gros objets devront être alloués à l'avenir.

algorithme de marquage-copie

Afin de résoudre le problème de fragmentation de la mémoire, la mémoire disponible est divisée en deux morceaux de taille égale en fonction de la capacité, et un seul d'entre eux est utilisé à la fois. Lorsque l'espace utilisé est épuisé, copiez l'objet survivant sur une autre pièce, puis nettoyez l'espace mémoire utilisé en une seule fois. Principalement utilisé pour la nouvelle génération.

La mise en œuvre est simple, le fonctionnement est efficace et le problème de fragmentation de la mémoire est résolu. Le prix est que la mémoire disponible est réduite de moitié, gaspillant de l'espace.

HotSpot divise la nouvelle génération en un Eden plus grand et deux Survivants plus petits, et n'utilise qu'Eden et l'un des Survivants pour chaque allocation de mémoire. Pendant la collecte des ordures, copiez les objets survivants d'Eden et de Survivor dans un autre morceau de Survivor en même temps, puis nettoyez directement Eden et le morceau utilisé de Survivor. Le ratio par défaut d'Eden sur Survivor de HotSpot est de 8:1, c'est-à-dire que l'espace disponible dans chaque nouvelle génération est de 90% de l'ensemble de la nouvelle génération.

Algorithme d'assemblage de marques

L'algorithme de marquage-copie doit effectuer plus d'opérations de copie lorsque le taux de survie des objets est élevé et que l'efficacité est faible. Si vous ne voulez pas perdre d'espace, vous avez besoin de garanties d'allocation d'espace supplémentaires pour faire face aux situations extrêmes où tous les objets de la mémoire utilisée survivent, donc cet algorithme n'est généralement pas utilisé dans l'ancienne génération.

L'ancienne génération utilise l'algorithme d'organisation des marques. Le processus de marquage est le même que l'algorithme d'effacement des marques, mais au lieu de nettoyer directement les objets recyclables, tous les objets survivants sont déplacés vers une extrémité de l'espace mémoire, puis la mémoire à l'extérieur. la frontière est nettoyée.

La différence entre mark-sweep et mark-sort est que le premier est un algorithme immobile tandis que le second est mobile. Si vous déplacez des objets survivants, en particulier dans la zone de vieillesse où un grand nombre d'objets survivent à chaque collection, il s'agit d'une opération extrêmement lourde et le thread utilisateur doit être suspendu tout au long du déplacement. Si l'objet n'est pas déplacé, cela entraînera des problèmes de fragmentation de l'espace, qui ne peuvent être résolus qu'en s'appuyant sur des allocations de mémoire et des accesseurs plus complexes.

7. Existe-t-il un moyen de vérifier la mémoire hors tas ?
Pour la mémoire occupée par le processus, vous pouvez utiliser la commande top pour voir la valeur occupée par le segment RES. Si cette valeur dépasse largement la mémoire de tas maximale que nous avons définie, cela prouve que la mémoire hors tas occupe une grande surface.

Utilisez gdb pour vider la mémoire physique, et vous pouvez généralement voir le contenu à l'intérieur. Une analyse plus complexe peut utiliser l'outil perf ou les gperftools open source de Google. Les fonctions natives qui s'appliquent le plus à la mémoire peuvent être facilement trouvées.

8. SWAP affectera-t-il les performances ?
Lorsque la mémoire du système d'exploitation est insuffisante, certaines données seront écrites sur le point d'échange SWAP, mais les performances de SWAP sont relativement faibles. Si l'application a un grand nombre de visites et doit fréquemment demander et détruire de la mémoire, elle est susceptible de se bloquer. Généralement, dans les scénarios à forte concurrence, SWAP est désactivé.

9. Savez-vous quel réglage des performances JVM
pour définir la taille de la mémoire du tas

1. -Xmx : La limite maximale de mémoire de tas. Définissez la taille de la jeune génération. La nouvelle génération ne doit pas être trop petite, sinon un grand nombre d'objets afflueront dans l'ancienne génération

2. -XX:NewSize : taille de nouvelle génération

3. -XX:NewRatio Part de la nouvelle génération et de l'ancienne génération

4. -XX:SurvivorRatio : le rapport entre l'espace Eden et l'espace survivant

5. Définissez le substitut jeune du ramasse-miettes -XX:+UseParNewGC ancien substitut -XX:+UseConcMarkSweepGC

10. Quelles méthodes avez-vous pour résoudre les problèmes de débordement de mémoire ?
(Ce sujet est très vaste, vous pouvez en choisir un dans la session d'entraînement pour le résumé, voici un exemple du plus courant)

vous pouvez revenir de manière régulière

Le débordement de mémoire comprend de nombreuses situations, et la plus courante que je rencontre dans mon travail quotidien est le débordement de tas. Il y a eu un échec sur la ligne une fois, et après le redémarrage, à l'aide de la commande jstat, il a été constaté que la zone Ancienne augmentait. J'ai utilisé la commande jmap pour exporter une pile en ligne, puis j'ai utilisé MAT pour l'analyse. Grâce à l'analyse de GC Roots, j'ai trouvé un objet HashMap très volumineux, qui était à l'origine utilisé par un camarade de classe comme cache, mais un cache illimité a entraîné une augmentation continue de l'utilisation de la mémoire du tas. Plus tard, ce cache a été changé en cache de goyave, et une référence faible a été définie, et le défaut a disparu.

Cette réponse n'est pas très brillante, mais c'est vraiment un problème courant, et les gens ne peuvent pas le blâmer.

11. Pourquoi le chargement de classe utilise-t-il le modèle de délégation parentale ? Existe-t-il un scénario qui brise ce modèle ?
Une utilisation importante du modèle de délégation parent est de résoudre les problèmes de sécurité lors du chargement de la classe.

1. Supposons qu'un développeur écrive une classe nommée java.lang.Object pour tromper la JVM. Maintenant, il veut utiliser un ClassLoader personnalisé pour charger la classe java.lang.Object qu'il a écrite.

2. Heureusement, cependant, le modèle de délégation parentale ne lui permettra pas de réussir. Parce que la JVM va d'abord trouver la classe java.lang.Object sous le chemin Bootstrap ClassLoader et la charger

Le chargement des classes de Java suit-il nécessairement le modèle de délégation parentale ?

1. Dans le développement réel, nous pouvons casser ce mécanisme en personnalisant le ClassLoader et en réécrivant la méthode loadClass de la classe parent.

2. SPI rompt le mécanisme de délégation parent (SPI : Service Provider Discovery).

12. L'utilisation du processeur dans l'environnement de production est trop élevée, comment le résolvez-vous ?
1. La commande top + H trouve le pid du processus qui occupe le processeur le plus élevé

2, haut -H -p

Découvrez quels threads occupent le thread CPU le plus élevé dans ce processus et enregistrez le tid

3、jstack -l

threads.txt, exportez les informations de la pile de threads du processus vers le texte, s'il y a une exception dans l'exportation, ajoutez le paramètre -F

4. Convertissez tid en hexadécimal, recherchez dans threads.txt, trouvez la pile d'exécution de code de thread correspondante et trouvez la raison pour laquelle le processeur est relativement élevé dans le code. Où tid est converti en hexadécimal, vous pouvez utiliser la commande printf "%x" tid de Linux

J'ai utilisé la méthode ci-dessus pour découvrir que le problème CPU 100% causé par jvm multi-thread crazy full gc et la mise concurrente JDK1.6 HashMap ont causé le problème CPU 100% thread

13. Quel est le modèle de mémoire de la JVM ?
JVM essaie de définir un modèle de mémoire unifié, qui peut encapsuler les différences d'accès à la mémoire de divers matériels et systèmes d'exploitation sous-jacents, afin que les programmes Java puissent obtenir le même effet de concurrence sur différents matériels et systèmes d'exploitation. Elle est divisée en mémoire de travail et en mémoire principale. Les threads ne peuvent pas opérer directement sur la mémoire principale. Si un thread veut communiquer avec un autre thread, il ne peut être échangé qu'à travers la mémoire principale.

14. Quels types de GC connaissez-vous ?
GC mineur : GC qui survient dans la jeune génération. GC majeur : GC qui survient dans la vieillesse. GC complet : nettoyage complet du tas. Par exemple, la zone Metaspace provoque des collections jeunes et anciennes.

15. Comment juger qu'une constante est une constante obsolète ?
Le pool de constantes d'exécution recycle principalement les constantes obsolètes. Si la chaîne "abc" existe dans le pool de constantes, s'il n'y a pas d'objet String faisant actuellement référence à la constante de chaîne, cela signifie que la constante "abc" est une constante obsolète. Si la récupération de la mémoire se produit à ce moment et qu'elle est nécessaire, "abc" Il sera nettoyé du pool constant par le système.

16. Comprenez-vous la disposition de la mémoire de l'objet ?
La disposition de stockage des objets dans la mémoire de tas peut être divisée en en-tête d'objet, données d'instance et remplissage d'alignement.

L'en-tête d'objet occupe 12B, y compris les balises d'objet et les pointeurs de type. La marque d'objet stocke les données d'exécution de l'objet lui-même, telles que le code de hachage, l'âge de génération du GC, l'indicateur de verrouillage, l'ID de thread biaisé, etc. Cette partie occupe 8B et s'appelle Mark Word. Mark Word est conçu comme une structure de données dynamique afin de stocker plus de données dans un très petit espace et de réutiliser l'espace de stockage en fonction de l'état de l'objet.

Le pointeur de type est le pointeur de l'objet vers ses métadonnées de type, occupant 4B. La JVM utilise ce pointeur pour déterminer de quelle classe l'objet est une instance.

Les données d'instance sont les informations effectives réellement stockées par l'objet, c'est-à-dire les variables membres d'instance de cet objet de classe et toutes les variables membres de classe parent visibles. L'ordre de stockage sera affecté par l'ordre dans lequel les paramètres et les champs de la politique d'allocation des machines virtuelles sont définis dans le code source. Les champs de même largeur sont toujours alloués ensemble pour le stockage, et les variables définies dans la classe parent apparaîtront avant la sous-classe si la condition préalable est remplie.

Le rembourrage d'alignement n'est pas obligatoire, ce n'est qu'un espace réservé. Le système de gestion automatique de la mémoire de la machine virtuelle exige que la taille de tout objet soit un multiple de 8 B et que l'en-tête de l'objet ait été défini sur 1 ou 2 fois 8 B. Si les données d'instance d'objet ne sont pas alignées, elles doivent être rempli d'alignement.

17. Avez-vous déjà compris la disposition des objets Java ?
Les informations stockées ici dans la zone d'en-tête de l'objet comprennent deux parties : 1. Les propres données d'exécution de l'objet (MarkWord), qui occupent 8 octets pour stocker le code de hachage, l'âge générationnel du GC, la marque de type de verrouillage, l'ID de fil de verrouillage de polarisation, le fil de pointage de verrouillage CAS LockRecord pointeur, etc., le mécanisme de verrouillage synchronisé est étroitement lié à cette partie (markwork).Les trois bits les plus bas de la marque représentent l'état du verrou, dont l'un est un bit de verrouillage biaisé et les deux autres sont des bits de verrouillage communs . 2. Pointeur de type d'objet (pointeur de classe), occupant 4 octets, l'objet pointe vers son pointeur de métadonnées de classe et la JVM l'utilise pour déterminer de quelle instance de classe il s'agit.

Dans la zone de données d'instance, les informations réelles et valides de l'objet sont stockées ici, telles que le contenu de tous les champs de l'objet

L'implémentation de la JVM d'alignement de la zone de remplissage, HostSpot, stipule que l'adresse de départ de l'objet doit être un multiple entier de 8 octets. Elle est de 8 octets, donc HotSpot fait "l'alignement" afin de lire efficacement les objets. Si le la taille réelle de la mémoire d'un objet n'est pas un multiple entier de 8 octets, il "remplit" un multiple entier de 8 octets. Ainsi, la taille de la zone de remplissage d'alignement n'est pas fixe.

18. Parlez du modèle de délégation des parents
1. Modèle de délégation des parents, il est un peu inapproprié de traduire Parents en parents ici, car il n'y a qu'un seul parent dans le processus de chargement de classe et de transfert vers le haut ; parents signifie plus de niveaux ascendants .

2. En plus du chargeur de classe de démarrage de niveau supérieur, d'autres chargeurs de classe seront délégués à leurs chargeurs parents pour le chargement avant le chargement, et seront transmis couche par couche jusqu'à ce que tous les chargeurs de classe parent ne puissent pas être chargés de la classe.

3. Le modèle de délégation parentale résout mieux le problème de cohérence de la classe de base lorsque chaque chargeur de classe coopère, évite le chargement répété des classes et empêche la bibliothèque d'API principale d'être altérée à volonté.

Avant JDK 9

1. Démarrez le chargeur de classe (Bootstrp ClassLoader), chargez /lib/rt.jar, -Xbootclasspath

2. Extension ClassLoader (Extension ClassLoader) sun.misc.Launcher$ExtClassLoader, charger /lib/ext, java.ext.dirs

3. Application ClassLoader (Application ClassLoader, sun.misc.Launcher$AppClassLoader), charger CLASSPTH, -classpath, -cp, Manifest

4. Chargeur de classe personnalisé

À partir de JDK 9, Extension ClassLoader est remplacé par Platform ClassLoader. Le chargeur de classe de démarrage, le chargeur de classe de plate-forme et le chargeur de classe d'application héritent tous de jdk.internal.loader.BuiltinClassLoader

Logique de code de chargement de classe

classe synchronisée protégée<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { // Tout d'abord, vérifiez si la classe demandée a été chargée Class c = findLoadedClass(name); if (c == null) { try { if (parent != null) { c = parent.loadClass(name, false); } else { c = findBootstrapClassOrNull(name); } } catch (ClassNotFoundException e) { // Si le chargeur de classe parent lève ClassNotFoundException // Indique que le parent Le le chargeur de classe ne peut pas terminer la demande de chargement} if (c == null) { // Lorsque le chargeur de classe parent ne peut pas charger // alors appelez sa propre méthode findClass pour charger la classe c = findClass(name); } } if (resolve ) { resolveClass©; } return c; }

19. Quelles sont les étapes du CMS ?
Le CMS est obsolète. La vie est belle, le temps est limité, il n'est pas recommandé d'étudier plus avant. Si vous rencontrez des problèmes, recourez simplement au processus de recyclage.

1. Marque initiale

2. Marquage simultané

3. Pré-nettoyage simultané

4. Pré-nettoyage annulable simultané

5. Réétiqueter

6. Nettoyage simultané

En raison de la popularité du livre "Compréhension approfondie de la machine virtuelle Java", il n'y a généralement aucun problème à omettre les étapes 3 et 4 lors de l'entretien.

20. Expliquer l'espace de tas Java et GC ?
Lorsqu'un processus Java est démarré par la commande Java, de la mémoire lui est allouée. Une partie de la mémoire est utilisée pour créer l'espace de tas, et lorsqu'un objet est créé dans le programme, la mémoire est allouée à partir de l'espace. GC est un processus à l'intérieur de la JVM qui récupère la mémoire des objets invalides pour de futures allocations.

21. Le tas
est le plus grand élément de gestion de la mémoire JVM. Il est partagé par les threads. Le but est de stocker les instances d'objet. Presque toutes les instances d'objet souhaitées seront placées ici. Lorsqu'il n'y a pas d'espace disponible dans le tas, une exception OOM Selon la survie de l'objet Le cycle est différent, la JVM gère les objets en générations, et le ramasse-miettes effectue la gestion du ramasse-miettes

22. Ancienne génération et algorithme Mark Copy
L'ancienne génération adopte l'algorithme Mark-Compact car seul un petit nombre d'objets sont recyclés à chaque fois.

1. La génération permanente (Permanet Generation) dans la zone de méthode mentionnée par la machine virtuelle JAVA est utilisée pour stocker des classes, des constantes, des descriptions de méthodes, etc. La collection de la génération permanente comprend principalement des constantes obsolètes et des classes inutiles.

2. L'allocation de mémoire des objets se fait principalement dans l'espace Eden de la nouvelle génération et dans l'espace From de l'espace Survivor (où Survivor stocke actuellement des objets), et dans quelques cas, elle sera directement allouée à l'ancienne génération.

3. Lorsque l'Eden Space et l'Espace From de la nouvelle génération sont insuffisants, un GC se produira. Après le GC, les objets survivants dans l'Eden Space et From Space seront déplacés vers l'Espace To, puis l'Eden Space et From L'espace sera nettoyé.

4. Si To Space ne peut pas stocker suffisamment un objet, stockez cet objet dans l'ancienne génération.

5. Après GC, Eden Space et To Space sont utilisés, et le cycle se répète.

6. Lorsque l'objet s'échappe une fois du GC dans Survivor, son âge sera de +1. Par défaut, les objets dont l'âge atteint 15 ans seront déplacés vers l'ancienne génération.

23. Recyclage générationnel
Le recyclage générationnel repose sur deux faits : la plupart des objets ne seront pas utilisés de sitôt, et certains objets ne seront pas inutiles immédiatement, mais ils ne dureront pas longtemps

jeune génération->marquer-copier

Ancienne génération -> Mark-Clear

24. Parlez de la différence entre le tas et la pile
1. L'allocation d'adresses physiques du tas d'adresses physiques n'est pas continue jusqu'à l'objet. D'où les performances plus lentes. L'allocation discontinue doit également être prise en compte pendant le GC, il existe donc différents algorithmes. Par exemple, élimination des marques, copie, compression des marques et générationnel (c'est-à-dire que la nouvelle génération utilise l'algorithme de copie et que l'ancienne génération utilise la compression des marques). La pile utilise la pile dans la structure de données en continu. Les performances sont donc rapides.

2. Étant donné que le segment de mémoire est discontinu, la mémoire allouée est confirmée au moment de l'exécution, de sorte que la taille n'est pas fixe. La taille générale du tas est beaucoup plus grande que la pile. La pile est continue, donc la taille de la mémoire allouée doit être confirmée au moment de la compilation, et la taille est fixe.

3. Contenu stocké Le tas stocke des instances d'objets et des tableaux. Par conséquent, cette zone accorde plus d'attention à la pile de stockage des données : variables locales, pile d'opérandes et résultats de retour. Ce domaine est plus concerné par l'exécution des méthodes de programme.

4. Visibilité du programme Le tas est partagé et visible pour toute l'application. La pile n'est visible que pour les threads. C'est donc aussi un thread privé. Son cycle de vie est le même que celui du fil.

25. La méthode zone/génération permanente (partage de threads)
est ce que l'on appelle souvent la génération permanente (Permanent Generation), qui sert à stocker des données telles que des informations de classe chargées par la JVM, des constantes, des variables statiques et du code compilé par la compiler.HotSpot La VM étend la collecte générationnelle GC à la zone de méthode, c'est-à-dire qu'elle utilise la génération permanente du tas Java pour implémenter la zone de méthode, afin que le ramasse-miettes HotSpot puisse gérer cette partie de la mémoire comme le tas Java, sans avoir développer une mémoire spéciale pour le gestionnaire de zone de méthode (l'objectif principal de la récupération de mémoire de la ceinture permanente est la récupération du pool constant et le déchargement des types, donc les avantages sont généralement faibles).

Le Runtime Constant Pool fait partie de la zone des méthodes. En plus de la version de la classe, des champs, des méthodes, des interfaces et d'autres descriptions dans le fichier Class, il existe également un pool de constantes (Constant Pool Table), qui est utilisé pour stocker divers littéraux et références de symboles générés lors de la compilation. sera stocké dans le pool de constantes d'exécution dans la zone de méthode après le chargement de la classe. La machine virtuelle Java a des règles strictes sur le format de chaque partie du fichier Class (y compris le pool de constantes naturellement). Les données que chaque octet est utilisé pour stocker doivent répondre aux exigences de la spécification, afin qu'elles soient reconnues par le machine virtuelle Charger et exécuter.

26. Chargeur de classe
L'équipe de conception de la machine virtuelle implémente l'action de chargement en dehors de la JVM afin que l'application puisse décider comment obtenir les classes requises. La JVM fournit 3 types de chargeurs :

Bootstrap ClassLoader

Responsable du chargement des classes dans le répertoire JAVA_HOME\lib, ou dans le chemin spécifié par le paramètre -Xbootclasspath, et reconnu par la machine virtuelle (identifiée par le nom du fichier, tel que rt.jar).

Chargeur de classe d'extension

Responsable du chargement de la bibliothèque de classes dans le répertoire JAVA_HOME\lib\ext ou dans le chemin spécifié par la variable système java.ext.dirs.

Chargeur de classe d'application :

Responsable du chargement des bibliothèques de classes sur le chemin de l'utilisateur (classpath). La JVM charge les classes via le modèle de délégation parent.Bien sûr, nous pouvons également implémenter un chargeur de classe personnalisé en héritant de java.lang.ClassLoader.

27. Parler de la génération permanente
1. Avant JDK 8, l'implémentation de la zone de méthode dans Hotspot est la génération permanente (Perm)

2. JDK 7 a commencé à déplacer le pool de constantes de chaîne et les variables statiques initialement placées dans la génération permanente vers le tas. JDK 8 a commencé à supprimer la génération permanente et à utiliser le méta-espace. Le contenu restant de la génération permanente a été déplacé vers le méta-espace, et le métaspace était directement alloué en mémoire locale.

28. A quoi sert le pointeur coloré dans le collecteur ZGC ?
Les pointeurs colorés sont une technique qui stocke directement une petite quantité d'informations supplémentaires sur le pointeur, mais pourquoi le pointeur lui-même peut-il également stocker des informations supplémentaires ? Dans un système 64 bits, la mémoire théoriquement accessible est jusqu'à 16 octets (2 à la puissance 64) [3]. En fait, sur la base de considérations de demande (moins que beaucoup de mémoire est utilisée), de performances (plus l'adresse est large, plus il faut de niveaux de table de pages pour la conversion d'adresse) et de coût (plus de transistors sont consommés), l'architecture AMD64 [4 ] Ne prend en charge que le bus d'adresse 52 bits (4 Po) et l'espace d'adressage virtuel 48 bits (256 To), de sorte que la mémoire maximale que le matériel 64 bits peut réellement prendre en charge n'est que de 256 To. En outre, le côté système d'exploitation imposera également ses propres contraintes.Linux 64 bits prend en charge l'espace d'adressage virtuel de processus 47 bits (128 To) et l'espace d'adressage physique 46 bits (64 To), et le système Windows 64 bits ne prend même en charge que 44 bits. -bit (16 To) d'espace d'adressage physique. Bien que les 18 bits supérieurs du pointeur 64 bits sous Linux ne puissent pas être utilisés pour l'adressage, la mémoire de 64 To prise en charge par les pointeurs 46 bits restants peut toujours répondre pleinement aux besoins des gros serveurs actuels. Compte tenu de cela, la technologie de pointeur coloré de ZGC continue de se concentrer sur la largeur de pointeur de 46 bits restante et extrait ses 4 bits supérieurs pour stocker quatre informations de drapeau. Grâce à ces indicateurs, la machine virtuelle peut directement voir l'état de la marque tricolore de son objet référencé à partir du pointeur, si elle est entrée dans l'ensemble de réallocation (c'est-à-dire si elle a été déplacée) et si elle n'est accessible que via la touche de finalisation. () méthode. Bien sûr, étant donné que ces bits d'indicateur compriment davantage l'espace d'adressage original de 46 bits, la mémoire que ZGC peut gérer ne peut pas dépasser 4 To (2 à la puissance 42).

29. Comment déterminer les déchets lors de la récupération de place JVM ? Que sont les GC Roots ?
La JVM utilise l'algorithme d'analyse d'accessibilité. La JVM détermine la survie des objets via GC Roots. Le traçage et la recherche à partir de GC Roots généreront une chaîne appelée chaîne de référence. Lorsqu'un objet ne peut être lié à aucune racine GC, il est considéré comme un déchet.

Les racines GC comprennent généralement :

1. Diverses références liées aux threads actifs, telles que les références dans les cadres de pile dans la pile de la machine virtuelle.

2. Références aux variables statiques de la classe.

3. Références JNI, etc.

Bien sûr, il existe des réponses plus détaillées, je pense personnellement que cela suffit. La version détaillée est la suivante :

1. Dans le thread Java, les paramètres de type de référence, les variables locales, les valeurs temporaires, etc. de toutes les méthodes actuellement appelées. C'est-à-dire diverses références liées à notre cadre de pile.

2. Toutes les classes Java actuellement chargées.

3. Variable statique de type référence dans la classe Java.

4. La constante de type de référence (type Chaîne ou Classe) dans le pool de constantes d'exécution.

5. Certaines références aux structures de données internes de la JVM, telles que la classe sun.jvm.hotspot.memory.Universe.

6. L'objet de surveillance utilisé pour la synchronisation, tel que l'appel de la méthode wait() de l'objet.

7. Poignées JNI, y compris poignées globales et poignées locales

30. Qu'est-ce qu'une barrière de mémoire ?
Une barrière de mémoire, également appelée barrière de mémoire, est une instruction CPU utilisée pour contrôler les problèmes de réorganisation et de visibilité de la mémoire dans certaines conditions. Barrière LoadLoad : pour une telle instruction Load1 ; LoadLoad ; Load2, avant l'accès aux données à lire par Load2 et aux opérations de lecture ultérieures, les données à lire par Load1 sont garanties d'être lues. Barrière StoreStore : pour une telle instruction Store1 ; StoreStore ; Store2, avant que Store2 et les opérations d'écriture suivantes ne soient exécutées, l'opération d'écriture de Store1 est garantie d'être visible pour les autres processeurs. Barrière LoadStore : pour une telle instruction Load1 ; LoadStore ; Store2, avant que Store2 et les opérations d'écriture suivantes ne soient vidées, il est garanti que les données à lire par Load1 sont complètement lues. Barrière StoreLoad : pour une telle instruction Store1 ; StoreLoad ; Load2, avant l'exécution de Load2 et de toutes les opérations de lecture ultérieures, les écritures sur Store1 sont garanties d'être visibles pour tous les processeurs. Sa surcharge est la plus grande des quatre barrières. Dans la plupart des implémentations de processeur, cette barrière est une barrière universelle qui fonctionne comme les trois autres barrières de mémoire.

おすすめ

転載: blog.csdn.net/m0_54861649/article/details/126605489