Java Performance Chapitre 5 Bases de la récupération de place

O'Reilly Japan \ -Java Performance Résumé du chapitre 5 de ce livre

Chapitre 1 Introduction \ -Qiita Chapitre 2 Approche des tests de performances \ -Qiita Chapitre 3 Java Performance Toolbox \ -Qiita Chapitre 4 Mécanisme du compilateur JIT \ -Qiita ← Article précédent

5.1 Présentation de la récupération de place

L'attrait de Java est que les développeurs n'ont pas à être conscients du cycle de vie des objets. Cependant, cela peut être une faiblesse lors de l'optimisation de l'utilisation de la mémoire. D'après l'expérience de l'auteur de ce livre, le temps passé à travailler sur la mémoire Java est plus court que le temps passé à écraser les bogues liés aux pointeurs pendants et aux pointeurs nuls dans d'autres langages.

S'il n'est référencé de nulle part, il sera soumis à CG. Cependant, même s'il existe une liste avec une structure dans laquelle un élément fait référence à l'élément suivant, comme une liste concaténée, la liste entière peut être libérée si la liste elle-même n'est pas référencée.

Il recherche régulièrement dans le tas les objets inutilisés. Vous devez combiner des zones de mémoire quelque part pour éviter la fragmentation de la mémoire.

Les performances du garbage collection sont déterminées par les trois suivants.

--Découverte d'objets inutilisés --Mémoire libre

Lors de la recherche de références d'objets ou du déplacement d'objets en mémoire, le thread d'application doit conserver ces objets inutilisés. L'arrêt d'un thread d'application est appelé pause stop-the-world.

Garbage collector basé sur la génération

La zone de tas est divisée dans les zones suivantes.

La raison pour laquelle il est divisé en plusieurs parties est que la plupart des objets ne sont utilisés que pendant une courte période.

L'objet est d'abord affecté à eden dans la zone jeune.

Pour les garbage collection mineurs, lorsque cette zone est pleine, le garbage collector arrête tous les threads d'application, déplace les objets utilisés vers une autre zone et vide la zone jeune (les objets inutilisés disparaissent). ).

Cette méthode présente deux avantages:

Se déplacer à plusieurs reprises dans l'ancienne zone remplit l'ancienne zone. Le traitement de l'ancienne zone dépend de l'algorithme de garbage collection.

Le processus est compliqué, mais CMS et G1 peuvent rechercher des objets inutilisés sans arrêter le thread d'application. Cependant, il consomme plus de cycles CPU. Ces garbage collection peuvent également être des garbage collection complets. L'un des principaux objectifs du réglage des garbage collection simultanés est d'éviter les garbage collection complets.

Instructions pour le ramasse-miettes à utiliser

Si le temps de réponse est important L'arrêt des threads (en particulier le garbage collection complet) a un certain impact sur les demandes, mais si vous souhaitez le supprimer, le garbage collection simultané Si le temps de réponse moyen est important, le collecteur de garage de débit

S'il s'agit d'un type de traitement par lots Garbage collection de type simultané si les ressources du processeur sont disponibles. Vous pouvez éviter l'arrêt en raison de la récupération de place complète et terminer le processus plus rapidement. Si les ressources du processeur sont limitées, ce sera encore plus lent.

Algorithme de récupération de place

Ils sont quatre

1. Ramasse-miettes série

Le plus simple. Il n'y a qu'un seul thread qui traite le tas. Arrêtez et exécutez les threads d'application pour les garbage collection mineurs et complets. Peut être activé avec -XX: + UseSerialGC.

2. Tout au long du ramasse-miettes

Le garbage collection mineur est plus rapide que le type série car il utilise plusieurs threads pour traiter la zone jeune. Activer -XX:+UseParallelGC -XX: + UseParallelOldGC (Utilisez plusieurs threads pour traiter l'ancienne zone) Et.

3. Collecteur de déchets CMS

CMS (Concurrent Mark Sweep) a été conçu pour éviter les longues interruptions associées à une récupération complète de la mémoire. Les threads d'application s'arrêtent uniquement pendant le garbage collection mineur. Il consomme à la place des ressources CPU. Les threads d'arrière-plan ne se compactent pas, le tas reste donc fragmenté. S'il n'y a pas assez de ressources CPU, ou si la fragmentation du tas progresse et que les objets ne peuvent pas être alloués, la même opération que le type série est effectuée. Activer -XX:+UseConcMarkSweepGC -XX:+UseParNewGC Et.

4. Garbage Collector G1

G1 (Garbage 1st) vise à traiter un gros tas (4 Go ou plus) avec un temps d'arrêt minimum. Le tas est divisé en plusieurs régions pour le traitement. Copiez les objets utilisés dans une région vers une autre région. Ensuite, la théorie est qu'il est automatiquement (partiellement) compacté. Comme CMS, il évite le garbage collection complet, donc il consomme beaucoup de ressources CPU. Activer -XX:+UseG1GC Et.

Exécution forcée et désactivation du garbage collection

Un ramassage des ordures mineur se produit lorsque la zone jeune est pleine. Le garbage collection complet se produit lorsque l'ancienne zone est pleine. Le garbage collection simultané se produit lorsque le tas est sur le point de se remplir.

Il n'y a pas grand-chose à faire pour forcer un garbage collection avec System.gc (). Le garbage collection complet est toujours effectué même si le garbage collection CMS ou G1 est utilisé. Le simple fait de déplacer le ramasse-miettes qui se produira avant la planification n'améliorera pas les performances. Cependant, cela a du sens lorsqu'il s'agit de surveillance des performances et de mesures de référence. Le ramassage des ordures peut être effectué avant que la mesure et la mesure puissent être effectuées dans un état propre. La collecte par gavage avant la sortie du vidage du tas a également l'avantage de faciliter l'analyse du tas (bien que dans la plupart des cas, la plupart des méthodes d'acquisition du vidage du tas effectuent automatiquement le ramassage des ordures).

La récupération de place peut être générée avec jcmd $ {ID de processus} GC.run. Vous pouvez également le faire avec jconsole.

Dans RMI (appel de méthode à distance), System.gc () est exécuté toutes les heures en tant que mécanisme du garbage collector distribué.

Si vous voulez désactiver l'appel à System.gc (), vous pouvez le faire avec -XX: + DisableExplicitGC.

Sélection d'algorithme de récupération de place

Le ramasse-miettes série n'est efficace que lorsque la mémoire utilisée est de 100 Mo ou moins. Pour la plupart des programmes, le type de débit ou le type simultané est sélectionné.

Décidez lequel utiliser en fonction des objectifs de performance décrits au chapitre 2. Tenez compte du temps d'exécution, du débit et de la valeur moyenne (ou 90e centile) de votre application.

Le garbage collection simultané convient au traitement par lots qui ne consomme pas toutes les ressources du processeur. Le garbage collection de type débit convient au traitement par lots qui consomme toutes les ressources du processeur.

Les performances du CMS peuvent être considérablement dégradées en raison des ressources CPU limitées qui ne peuvent pas se permettre d'exécuter les threads d'arrière-plan du CMS. Cet état est appelé échec du mode simultané.

En termes de temps de réponse moyen, le garbage collection de type débit est plus élevé, À la valeur du 90e centile, le CMS peut être plus élevé.

Fondamentalement, CMS est plus rapide que G1 lorsque la taille du tas est de 4 Go ou moins.

Le thread d'arrière-plan du CMS scanne toute l'ancienne zone avant de libérer l'objet. Le temps de numérisation est proportionnel à la taille de la zone. Si le tas se remplit avant de scanner et de libérer des objets, un échec de mode simultané se produit. Lorsque cela se produit, arrêtez tous les threads d'application et effectuez un garbage collection complet. Les performances en souffrent car un seul thread est utilisé dans un garbage collection complet. Il est possible de régler pour utiliser plusieurs threads ici, mais le traitement de chaque thread augmentera en conséquence. La probabilité d'une panne de mode simultané affecte également la quantité de mémoire allouée.

D'autre part, dans le garbage collector G1, l'ancienne zone est divisée par région, il est donc possible de traiter l'analyse de l'ancienne zone dans un thread distinct pour chaque région. Même si le traitement de ces threads ne peut pas suivre, l'échec du mode simultané peut se produire, mais en raison du mécanisme, il ne se produit pas très souvent.

Dans CMS, il est facile d'être fragmenté car il n'est pas compacté sauf pour un garbage collection complet.

Il est peu probable que la fragmentation du tas se produise dans G1.

Il existe des méthodes de réglage dans CMS et G1 pour éviter les échecs de mode simultané.

5.2 Réglage de base du ramasse-miettes

Changer la taille du tas

Si le tas est petit, vous devrez tout le temps faire un garbage collection. Le temps de pause qui se produit pendant le garbage collection augmente proportionnellement à la taille du tas.

Si vous spécifiez une zone de tas plus grande que la mémoire physique ... La JVM ne distingue pas s'il s'agit d'une zone d'échange ou non. Par conséquent, les applications Java essaient d'utiliser pleinement la zone de tas spécifiée, ce qui affecte les performances. En outre, pendant le garbage collection complet, l'intégralité du tas est accédée, donc l'échange se produit toujours. Ensuite, le garbage collection n'est pas à temps, ce qui entraîne un échec du mode simultané. Donc ** la taille du tas ne doit pas dépasser la quantité de mémoire physique. ** ** La mémoire physique doit avoir une marge de 1 Go pour la JVM elle-même et les autres applications.

La taille du tas est spécifiée avec une valeur initiale de «-XmsN» et une valeur maximale de «-XmxN». La valeur par défaut diffère en fonction du système d'exploitation, de la capacité de mémoire et du type de JVM. La JVM s'accorde automatiquement entre les valeurs initiale et maximale. Si la taille actuelle du tas entraîne trop de garbage collection, augmentez continuellement la taille du tas.

En général, il est souhaitable d'avoir une taille de segment de mémoire utilisée à 30% après le garbage collection complet.

Réglage de la taille de chaque zone

---XX: NewRatio = N: Rapport entre l'ancienne zone et la zone jeune (la valeur par défaut est 2) ---XX: NewSize = N: young Taille initiale de la zone ---XX: MaxNewSize = N: La taille maximale de la zone jeune ---XmnN: notation courte pour rendre NewSize et MaxNewSize la même valeur

La taille initiale de la jeune région est calculée ci-dessous.

Taille initiale de la zone jeune=Taille initiale du tas/(1 + NewRatio)

Par défaut, la taille initiale de la zone jeune est de 33% de la taille initiale du tas (vous pouvez également la spécifier avec le drapeau NewSize).

Redimensionner la zone permanente et la méta-espace

La JVM contient des données sur la classe. La zone est appelée zone permanente jusqu'à Java 7, et est appelée métaspace après Java 8. La zone permanente de Java7 contenait diverses informations qui n'avaient rien à voir avec les données de la classe, mais à partir de Java8, elles ont été déplacées vers le tas normal.

La zone permanente et la méta-espace sont des zones utilisées par le compilateur JIT et la JVM, donc ils en sont à peine conscients.

La zone permanente a une limite supérieure, mais la méta-espace n'a pas de limite supérieure par défaut (il n'est presque pas nécessaire de spécifier la taille de la limite supérieure), Si tu le mets Paramètres de zone permanente: -XX: PermSize = N, -XX: MaxPermSize = N Paramètres de Metaspace: -XX: MetaspaceSize = N, -XX: MaxMetaspaceSize = N

Il y a des cas où le méta-espace consomme de la mémoire, mais il peut être analysé par NMT (Native Memory Tracking) présenté au chapitre 8. (Est-ce le cas lorsque le système devient trop énorme et que le nombre de classes augmente? Il semble préférable de penser à la division des services avant que cela ne se produise.)

Le redimensionnement des zones permanentes et des métaspaces est lent car il implique la récupération de place. Si le garbage collection est répété au démarrage, la zone permanente et la métaspace peuvent avoir été développées. Dans un tel cas, augmentez la taille initiale.

Vous pouvez obtenir des informations sur le chargeur de classe à l'aide du vidage de tas décrit au chapitre 7. Vous pouvez voir si la zone permanente ou métaspace est pleine de données du chargeur de classe. Vous pouvez obtenir des informations sur le chargeur de classe en démarrant jmap avec -clstats ( -permstat pour Java 7).

Spécifier le degré de parallélisme

Autre que le type série, un garbage collection multi-thread est effectué. Vous pouvez spécifier le nombre de threads avec -XX: ParallelGCThreads = N.

Par défaut, il existe un thread par CPU, mais s'il dépasse 8, le nombre de threads est déterminé par la formule suivante.

Nombre de threads dans le garbage collection= 8 + 5(N - 8)/8

Si plusieurs JVM sont en cours d'exécution, vous devez réduire le nombre de threads.

Étant donné que l'efficacité du garbage collection est élevée, 100% du processeur est utilisé.

adaptive sizing La taille de la zone de tas et de l'espace survivant est modifiée de manière dynamique pendant l'exécution. Ce mouvement est appelé dimensionnement adaptatif. L'avantage est que même si vous définissez une valeur élevée pour la valeur maximale, elle sera automatiquement développée sans la situation où vous risquez de surutiliser le tas même si vous ne l'utilisez pas.

Le redimensionnement prend du temps. La plupart d'entre eux sont arrêtés par le garbage collection. Si vous spécifiez les paramètres de la récupération de place en détail et que vous connaissez la taille de tas requise, vous pouvez désactiver le dimensionnement adaptatif. Il peut être désactivé avec -XX: -UseAdaptiveSizePolicy.

Si vous utilisez -XX: + PrintAdaptiveSizePolicy, vous pouvez voir comment chaque espace est développé.

Outils liés à la collecte des ordures

Il est judicieux de consulter le journal du garbage collection pour voir dans quelle mesure le garbage collection affecte votre application. Avec -verbose: gc ou -XX: + PrintGC, le journal GC sera affiché. -XX: + PrintGCDetails vous donnera un journal plus détaillé. Spécifiez également -XX: + PrintGCTimeStamps ou -XX: + PrintGCDateStamps. Vous pouvez changer la destination de sortie avec -Xloggc: $ {nom de fichier}. Les indicateurs liés à la rotation des journaux sont les suivants. -XX:+UseGCLogFileRotation, -XX:NumberOfGCLogFiles=N, -XX:GCLogFileSize=N Vous pouvez générer des graphiques et des tableaux en chargeant un fichier journal dans un outil appelé Histogramme GC.

jstat -gcutil ${ID de processus} 1000

Vous pouvez démarrer le journal GC de l'application Java dans.

Recommended Posts

Java Performance Chapitre 5 Bases de la récupération de place
Java Performance Chapitre 1 Introduction
Java Performance Chapitre 3 Boîte à outils Java Performance
Java Performance Chapter 2 Approche des tests de performances
Les bases de Java
Les bases de Java
Les bases de Java
Efficace Java Chapitre 2
bases de la programmation Java
Effective Java Chapitre 6 34-35
Réintroduction Java - Collection Java
Principes de base de Java JAR
Notions de base orientées objet (Java)
Principes de base du traitement parallèle Java
Collecte des ordures - Partie 1-
Effective Java Chapitre 4 15-22
Java efficace Chapitre 3
[Java] Cadre de collection
Java Performance Chapter 4 Fonctionnement du compilateur JIT
Collection expirée de java
Questions d'entretien de Java Collection
Réglage des performances de l'application Java
Bases de la programmation Java Practice-array
Principes de base du réseau Java (communication)
Muscle Java Basics Jour 1
Chapitre 2 Programmation réseau par JAVA phttpd Collecte d'exceptions en 3 endroits
Premiers pas avec Java Collection
J'ai commencé Java Gold (Chapitre 1-1)
Principes de base de l'utilisation des caractères (Java)
Collection d'exemples de code parallèle Java
Collecte des ordures G1 en 3 minutes
[Java] Comparateur de la classe Collection
Collection de méthodes de code de test Java
Instruction pratique de base de la programmation Java
Qu'est-ce qu'une collection Java?
Résumé des bases du langage Java
Premiers pas avec les bases de Java
Bases du développement Java ~ Exercice (tableau) ~
[Notions de base Java] Qu'est-ce que la classe?
Collecte de copies approfondies en Java
Collection de tâches de programmation sélectionnées à réaliser et à mémoriser (bases de Java)