JVM gère deux types de mémoire, tas et non tas. Le tas est destiné aux développeurs, comme mentionné ci-dessus, il est créé au démarrage de la JVM ; le non-heap est réservé à la JVM elle-même pour stocker les informations de classe. C'est différent du tas, GC ne libérera pas d'espace pendant l'exécution.
1. Type de débordement de mémoire
1. java.lang.OutOfMemoryError : espace PermGen
JVM gère deux types de mémoire, tas et non tas. Le tas est destiné aux développeurs, comme mentionné ci-dessus, il est créé au démarrage de la JVM ; le non-heap est réservé à la JVM elle-même pour stocker les informations de classe. C'est différent du tas, GC ne libérera pas d'espace pendant l'exécution. Si l'application Web utilise un grand nombre de fichiers JAR tiers ou si l'application contient trop de fichiers de classe et que le paramètre MaxPermSize s'avère petit, le dépassement de la limite entraînera également une occupation trop importante de la mémoire et provoquera un débordement, ou le Tomcat le fera. ne nettoie pas le front pendant le déploiement à chaud. L'environnement chargé ne fera que changer le contexte en celui nouvellement déployé, et il y aura de plus en plus de contenu non empilable.
Le nom complet de l'espace PermGen est Espace de génération permanente, qui fait référence à la zone de stockage permanente de la mémoire. Cette mémoire est principalement utilisée par la JVM pour stocker les informations de classe et les méta-classes seront placées dans l'espace PermGen. est chargé par Loader et il stocke les instances de classe. La zone de tas (instance) est différente, GC (Garbage Collection) ne nettoiera pas l'espace PermGen pendant l'exécution du programme principal, donc si votre application a beaucoup de CLASS, PermGen est susceptible d'apparaître. erreur d'espace, cette erreur est courante lorsque le serveur Web précompile JSP. Si votre WEB APP utilise un grand nombre de jars tiers, et que leur taille dépasse la taille par défaut du jvm (4M), ce message d'erreur sera généré.
Un meilleur exemple de configuration : (Après vérification par moi-même, depuis que j'utilise cette configuration, Tomcat n'est plus jamais mort)
définir JAVA_OPTS=-Xms800m -Xmx800m -XX:PermSize=128M -XX:MaxNewSize=256m -XX:MaxPermSize=256m
Sous Linux, ajoutez une ligne de code comme indiqué en rouge dans tomcathome/conf/catalina.sh : vous pouvez augmenter la mémoire de tomcat jvm, afin que les débordements de mémoire soient moins susceptibles de se produire !
# ----- Exécuter la commande demandée ---------------------------------------- -
JAVA_OPTS="-serveur -Xms512m -Xmx2048m -XX:PermSize=128m -XX:MaxNewSize=256m -XX:MaxPermSize=256m"
# Bugzilla 37848 : afficher ceci uniquement si nous avons un ATS
2. java.lang.OutOfMemoryError : espace Javaheap
La première situation est celle d’un supplément, et c’est dans cette situation que se pose le principal problème. Son espace par défaut (c'est-à-dire -Xms) est de 1/64 de la mémoire physique et l'espace maximum (-Xmx) est de 1/4 de la mémoire physique. S'il reste moins de 40 % de la mémoire, la JVM augmentera le tas à la valeur définie par Xmx. Si la mémoire restante dépasse 70 %, la JVM diminuera le tas à la valeur définie par Xms. Par conséquent, les paramètres Xmx et Xms du serveur doivent généralement être définis de la même manière pour éviter d'ajuster la taille du tas de la machine virtuelle après chaque GC. En supposant que la mémoire physique soit infinie, la mémoire JVM maximale dépend du système d'exploitation. Généralement, la machine 32 bits est comprise entre 1,5 g et 3 g, tandis que la machine 64 bits n'a pas de limite.
Remarque : Si Xms dépasse la valeur Xmx, ou si la somme de la valeur maximale du tas et de la valeur maximale hors tas dépasse la limite maximale de la mémoire physique ou du système d'exploitation, le serveur ne démarrera pas.
Le rôle du garbage collection GC
La fréquence des appels de la JVM à GC est encore très élevée et le garbage collection est effectué dans deux situations principales :
Lorsque le thread d'application est inactif ; l'autre est lorsque le tas de mémoire Java est insuffisant, le GC sera appelé en continu. Si le recyclage continu ne peut pas résoudre le problème de tas de mémoire insuffisant, une erreur de mémoire insuffisante sera signalée. Cette exception dépendant de l'environnement d'exploitation du système, il est impossible de prédire quand elle se produira.
Selon le mécanisme GC, l'exécution du programme entraînera des modifications dans l'environnement d'exploitation du système, augmentant ainsi les risques de déclenchement du GC.
Afin d'éviter ces problèmes, la conception et l'écriture de programmes doivent éviter l'occupation de la mémoire par des objets inutiles et la surcharge de GC. L'appel explicite de System.GC() ne peut que suggérer que la JVM doit recycler les objets inutiles en mémoire, mais il n'est pas nécessaire de les recycler immédiatement.
La première est que cela ne peut pas résoudre le problème de l’épuisement des ressources mémoire et qu’il augmentera également la consommation du GC.
2. Composition de la zone mémoire JVM <BR>Parlez simplement du tas et de la pile en Java
Java divise la mémoire en deux types : l’un est la mémoire de pile et l’autre la mémoire de tas.
1. Les variables de type de base et les variables de référence d'objet définies dans la fonction sont allouées dans la mémoire de pile de la fonction ;
2. La mémoire tas est utilisée pour stocker les objets et les tableaux créés par new. Lorsqu'une variable est définie dans une fonction (bloc de code), Java alloue de l'espace mémoire pour la variable sur la pile. Lorsque la portée de la variable est dépassée, Java le fera. Libérez-le automatiquement. Supprimez l'espace mémoire alloué à la variable ; la mémoire allouée dans le tas est gérée par le garbage collector automatique de la machine virtuelle Java. L'avantage du tas est que la taille mémoire peut être allouée dynamiquement, et la durée de vie. Il n'est pas nécessaire d'en informer le compilateur à l'avance, car il se trouve dans la mémoire allouée dynamiquement au moment de l'exécution. L'inconvénient est que la mémoire doit être allouée dynamiquement au moment de l'exécution et que la vitesse d'accès est lente ;
L'avantage de la pile est que la vitesse d'accès est plus rapide que celle du tas. L'inconvénient est que la taille et la durée de vie des données stockées dans la pile doivent être déterministes et rigides.
Le tas Java est divisé en trois zones : nouveau, ancien et permanent.
GC a deux threads :
Les objets nouvellement créés sont alloués à la nouvelle zone. Lorsque la zone est remplie, elle sera déplacée vers l'ancienne zone par le thread auxiliaire GC. Lorsque l'ancienne zone est également remplie, le thread principal GC sera déclenché pour parcourir tous les objets. la mémoire du tas. La taille de la zone Ancienne est égale à Xmx moins -Xmn
Ajustement de la pile de stockage de la pile Java : les paramètres sont +UseDefaultStackSize -Xss256K, ce qui signifie que chaque thread peut demander 256 000 espaces de pile. Chaque thread a sa propre pile.
3. Comment définir la mémoire virtuelle dans JVM <BR>Astuce : Dans JVM, si 98 % du temps est utilisé pour GC et que la taille du tas disponible est inférieure à 2 %, ce message d'exception sera émis.
Astuce : La taille maximale du segment de mémoire ne doit pas dépasser 80 % de la mémoire physique disponible. Généralement, les options -Xms et -Xmx doivent être définies sur la même valeur et -Xmn doit être égale à 1/4 de la valeur -Xmx.
Astuce : La mémoire initiale allouée par la JVM est spécifiée par -Xms et la valeur par défaut est 1/64 de la mémoire physique ; la mémoire maximale allouée par la JVM est spécifiée par -Xmx et la valeur par défaut est 1/4 de la mémoire physique. mémoire.
Par défaut, lorsque la mémoire du tas libre est inférieure à 40 %, la JVM augmentera le tas jusqu'à la limite maximale de -Xmx ; lorsque la mémoire du tas libre est supérieure à 70 %, la JVM réduira le tas jusqu'à la limite minimale de -Xms. Par conséquent, le serveur définit généralement -Xms et -Xmx comme étant égaux pour éviter d'ajuster la taille du tas après chaque GC.
Astuce : En supposant que la mémoire physique soit infinie, la valeur maximale de la mémoire JVM a une excellente relation avec le système d'exploitation.
Pour faire simple, même si un processeur 32 bits dispose d'un espace mémoire contrôlable de 4 Go, le système d'exploitation spécifique imposera une limite.
Cette limite est généralement de 2 Go à 3 Go (en général, elle est de 1,5 G à 2 G sous les systèmes Windows et de 2 G à 3 G sous les systèmes Linux), et il n'y aura aucune limite pour les processeurs supérieurs à 64 bits.
Remarque : Si Xms dépasse la valeur Xmx, ou si la somme de la valeur maximale du tas et de la valeur maximale hors tas dépasse la limite maximale de la mémoire physique ou du système d'exploitation, le serveur ne démarrera pas.
Astuce : définissez NewSize et MaxNewSize pour qu'ils soient égaux et la taille du "nouveau" ne doit pas être supérieure à la moitié de "l'ancien". La raison en est que si l'ancienne zone n'est pas assez grande, le GC "principal" sera déclenché fréquemment. , ce qui réduit considérablement les performances.
JVM utilise -XX:PermSize pour définir la valeur initiale de la mémoire non tas. La valeur par défaut est 1/64 de la mémoire physique ;
La taille maximale de la mémoire non tas est définie par XX:MaxPermSize. La valeur par défaut est 1/4 de la mémoire physique.
Solution : définir manuellement la taille du tas
Modifier TOMCAT_HOME/bin/catalina.bat
Ajoutez les lignes suivantes au-dessus de "echo "Using CATALINA_BASE: $CATALINA_BASE" :
JAVA_OPTS="-serveur -Xms800m -Xmx800m -XX:MaxNewSize=256m"
4. Utilisez les outils de vérification des performances pour localiser les fuites de mémoire :
L'outil JProfiler est principalement utilisé pour vérifier et suivre les performances des systèmes (limité au développement Java). JProfiler peut surveiller le fonctionnement et les performances de la JVM en surveillant constamment l'utilisation de la mémoire du système, le garbage collection, l'état d'exécution des threads et d'autres moyens à tout moment.
1. La mémoire du serveur d'applications est occupée de manière déraisonnable pendant une longue période. La mémoire est souvent occupée à un niveau élevé et est difficile à récupérer à un niveau bas.