L'objectif le plus fondamental de la gestion automatique de la mémoire dans le système technologique Java est de résoudre automatiquement deux problèmes : l'allocation automatique de mémoire aux objets et le recyclage automatique de la mémoire allouée aux objets.
1. Présentation
L'allocation de mémoire des objets, conceptuellement, doit être allouée sur le tas (en fait, elle peut également être désassemblée en types scalaires après une compilation juste à temps et allouée indirectement sur la pile). Dans le cadre du modèle de génération classique, les nouveaux objets sont généralement attribués à la jeune génération. Dans de rares cas (par exemple, la taille de l'objet dépasse un certain seuil), ils peuvent également être attribués directement à l'ancienne génération. Les règles d'allocation des objets ne sont pas fixes. La "Spécification de la machine virtuelle Java" ne stipule pas les détails de création et de stockage de nouveaux objets. Cela dépend du garbage collector actuellement utilisé par la machine virtuelle et des fonctions liées à la mémoire dans la machine virtuelle. . Paramètres.
Dans la plupart des cas, les objets sont alloués dans la zone Eden de nouvelle génération. Lorsque la zone Eden ne dispose pas de suffisamment d'espace pour l'allocation, la machine virtuelle lancera un GC mineur.
1. Lorsqu'il y a suffisamment d'espace dans la zone Eden
Paramètres de la machine virtuelle
-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8
Description des paramètres
Essayez d'allouer trois objets de 2 Mo et un de 4 Mo, et transmettez -Xms20M, -Xmx20M, -Xmn10M au moment de l'exécution. . Ce paramètre limite la taille du tas Java à 20 Mo et ne peut pas être étendu. 10 Mo sont alloués à la nouvelle génération et les 10 Mo restants sont alloués à l'ancienne génération. -XX : Survivor-Ratio=8 détermine que le rapport d'espace entre la zone Eden et une zone Survivor dans la nouvelle génération est de 8:1.
package com.xiao.test.Test; public class test { private static final int _1MB = 1024 * 1024; public static void main(String[] args) { byte[] byte1,byte2,byte3; byte1 = new byte[2 * _1MB]; byte2 = new byte[2 * _1MB]; byte3 = new byte[2 * _1MB]; } }
2. La situation où il n'y a pas assez d'espace dans la zone Eden
Les paramètres de la machine virtuelle sont les mêmes
package com.xiao.test.Test; public class test { private static final int _1MB = 1024 * 1024; public static void main(String[] args) { byte[] byte1,byte2,byte3,byte4; byte1 = new byte[2 * _1MB]; byte2 = new byte[2 * _1MB]; byte3 = new byte[2 * _1MB]; byte4 = new byte[3 * _1MB]; } }
Évidemment Minor GC
1. Qu'est-ce qu'un gros objet ?
Les gros objets font référence aux objets Java qui nécessitent une grande quantité d'espace mémoire continu. Les gros objets les plus typiques sont des chaînes ou des tableaux très longs avec un grand nombre d'éléments.
2. Raisons pour lesquelles les objets volumineux doivent être évités dans les machines virtuelles Java
Lors de l'allocation d'espace, cela peut facilement provoquer le déclenchement anticipé du garbage collection lorsqu'il y a évidemment beaucoup d'espace dans la mémoire, afin d'obtenir suffisamment d'espace continu. espace pour les placer correctement. Lors de la copie d'objets, les objets volumineux entraînent une surcharge de mémoire élevée pour la copie.
3. L'avantage des objets volumineux entrant directement dans l'ancienne génération
Évitez les allers-retours entre la zone Eden et les deux zones Survivor, ce qui entraînerait un grand nombre d'opérations de copie de mémoire (la machine virtuelle HotSpot fournit -XX : paramètre PretenureSizeThreshold , spécifiez une valeur supérieure à ce paramètre. Les objets de valeur sont alloués directement dans l'ancienne génération).
1. Comment la machine virtuelle détermine-t-elle si l'objet survit à long terme ?
Lorsque la mémoire est recyclée, elle doit être capable de décider quels objets survivants doivent être placés dans la nouvelle génération et quels objets survivants doivent être placés dans l'ancienne génération. Pour ce faire, la machine virtuelle définit un compteur d'âge d'objet (Age) pour chaque objet, qui est stocké dans l'en-tête de l'objet.
2. Le processus d'augmentation de l'âge des objets et de promotion vers l'ancienne génération
Les objets naissent généralement dans la zone Eden s'ils survivent encore après le premier GC mineur et peuvent être hébergés par le survivant, l'objet sera déplacé vers. l'espace Survivant et fixez l'âge de son objet à 1 an. Chaque fois qu'un objet survit à un GC mineur dans la zone Survivant, son âge augmente d'un an. Lorsque son âge atteint un certain niveau (15 par défaut), il sera promu à l'ancienne génération. Le seuil d'âge pour qu'un objet soit promu à l'ancienne génération peut être défini via le paramètre -XX : MaxTenuringThreshold.
3. La raison pour laquelle les objets à longue durée de vie entreront dans l'ancienne génération
Nous savons tous que l'algorithme de récupération de place de la nouvelle génération est un algorithme de marquage-copie si les objets à longue durée de vie sont toujours stockés dans la nouvelle génération, la copie se produira. Le problème de l’augmentation des frais généraux. Par conséquent, nous plaçons les objets dépassant un certain seuil d'âge dans l'ancienne génération, ce qui peut réduire la pression sur la nouvelle génération lors du ramassage des ordures.
Afin de mieux s'adapter aux conditions de mémoire des différents programmes, la machine virtuelle HotSpot n'exige pas toujours que l'âge de l'objet atteigne -XX:MaxTenuringThreshold avant de pouvoir être promu à l'ancienne génération. S'il est dans l'espace Survivant La somme des tailles de tous les objets du même âge est supérieure à la moitié de l'espace Survivant. Les objets dont l'âge est supérieur ou égal à cet âge peuvent entrer directement dans l'ancienne génération sans. en attente de l'âge requis dans -XX:MaxTenuringThreshold.
1 Contenu de la garantie d'attribution d'espace
.Avant que le GC mineur ne se produise, la machine virtuelle doit d'abord vérifier si l'espace continu maximum disponible dans l'ancienne génération est supérieur à l'espace total de tous les objets de la nouvelle génération. Si cette condition est vraie, alors cette fois le mineur. GC peut être garanti comme étant sûr. S'il n'est pas établi, la machine virtuelle vérifiera d'abord si la valeur de réglage du paramètre -XX : HandlePromotionFailure permet l'échec de la garantie ; si elle est autorisée, elle continuera à vérifier si l'espace continu maximum disponible dans l'ancienne génération est supérieur à ; la taille moyenne des objets promus à l'ancienne génération. Si elle est supérieure, un GC mineur sera tenté, bien que cette fois le GC mineur soit risqué s'il est inférieur, ou si le paramètre -XX : HandlePromotionFailure n'autorise pas de risque ; alors un GC complet sera effectué à la place.
2. Quel est le risque de "l'aventure"
Comme mentionné précédemment, la nouvelle génération utilise l'algorithme de collecte de copies, mais pour l'utilisation de la mémoire, un seul des espaces Survivor est utilisé Il est utilisé comme sauvegarde tournante, donc lorsqu'un grand nombre d'objets survivent encore après un GC mineur - le cas le plus extrême est que tous les objets de la nouvelle génération survivent après le recyclage de la mémoire, l'ancienne génération doit effectuer des garanties d'allocation, et les objets qui ne peuvent pas être hébergés par le Survivant peuvent être directement transférés. Envoyés dans la vieillesse, cela s'apparente aux garanties de prêt en viager. Pour garantir une telle garantie à l'ancienne génération, le principe est que l'ancienne génération elle-même dispose encore d'espace restant pour accueillir ces objets. Cependant, le nombre d'objets qui survivront à ce recyclage ne peut pas être clairement connu avant que le recyclage de la mémoire ne soit réellement terminé. ne peut prendre que La taille moyenne de la capacité de l'objet promu à l'ancienne génération lors de chaque recyclage précédent est utilisée comme valeur d'expérience. Elle est comparée à l'espace restant dans l'ancienne génération pour décider s'il faut effectuer un GC complet pour libérer plus d'espace. l'ancienne génération.
3. Devons-nous ouvrir la garantie ?
Comparer la moyenne historique est toujours une solution basée sur un pari sur la probabilité. C'est-à-dire que si le nombre d'objets après un certain GC mineur survit augmente soudainement, il est bien supérieur à la moyenne historique. Cela entraînera l’échec de la garantie. En cas de défaillance de la garantie, vous devez alors relancer Full GC honnêtement, le temps de pause sera donc très long. Bien que le cercle soit le plus grand lorsque la garantie échoue, le commutateur -XX: HandlePromotionFailure est généralement activé pour éviter que Full GC ne soit trop fréquent.
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!