Dans la machine virtuelle Java, la mémoire des objets et des tableaux est allouée dans le tas, et la mémoire principale récupérée par le garbage collector est dans la mémoire du tas. Si les objets ou tableaux créés dynamiquement ne sont pas recyclés à temps pendant l'exécution d'un programme Java et continuent de s'accumuler, la mémoire tas finira par être pleine, conduisant à un MOO.
JVM fournit un mécanisme de récupération de place, appelé mécanisme GC. Grâce au mécanisme GC, les objets indésirables dans le tas peuvent être recyclés en continu pendant le fonctionnement, garantissant ainsi le fonctionnement normal du programme.
Nous savons tous que les objets dits "garbage" font référence à des objets qui ne sont plus utiles lors de l'exécution de notre programme, c'est-à-dire des objets qui ne sont plus utiles. plus en vie. Alors comment juger si les objets dans le tas sont des « déchets » ou des objets qui ne sont plus vivants ?
Chaque objet possède un attribut de comptage de références, qui est utilisé pour enregistrer le nombre de fois où l'objet a été référencé. Lorsque le nombre de références est 0, cela signifie que l'objet n'a pas été référencé, que l'objet ne sera pas utilisé et qu'il peut être déterminé comme un objet poubelle. Cependant, cette méthode a un gros bug, c'est qu'elle ne peut pas résoudre le problème des références mutuelles ou des références circulaires entre objets : lorsque deux objets se réfèrent l'un à l'autre, ils n'ont aucune relation de référence avec d'autres objets, et ils ont le même numéro. de références n'est pas 0, il ne sera donc pas recyclé, mais en fait ces deux objets ne sont plus utiles.
Afin d'éviter les problèmes causés par l'utilisation du comptage de références, Java utilise la méthode d'analyse d'accessibilité pour déterminer les objets inutiles.
De cette façon, la relation de référence de tous les objets peut être imaginée comme un arbre. À partir du nœud racine GC Racine de l'arbre, tous les objets référencés sont parcourus. Les nœuds de l'arbre sont des objets accessibles. les objets qui ne sont pas au niveau du nœud sont des objets inaccessibles.
Alors, quel type d'objet peut être utilisé comme nœud racine de GC ?
Objets référencés dans la pile de machines virtuelles (table de variables locales dans la pile de frames)
Objets référencés par des propriétés statiques dans la zone de méthode
Objet référencé par des constantes dans la zone de méthode
Objet référencé par JNI dans la pile de méthodes locale
Le mécanisme de garbage collection, qu'il adopte la méthode de comptage de références ou la méthode d'analyse d'accessibilité, est lié à la référence de l'objet. Il existe quatre statuts de référence en Java :
et provoquer le problème. programme se termine anormalement plutôt que de le recycler. L'objet référencé par une référence forte. Par conséquent, les références fortes sont l’une des principales causes des fuites de mémoire Java. OutOfMemoryError
Différent de l'algorithme Mark-Clear, l'algorithme Mark-Compact ne nettoie pas directement la mémoire recyclable après le marquage, mais déplace tous les objets survivants vers une extrémité, puis efface le recyclable Récupérer la mémoire.
Algorithme de marquage-collage (avant recyclage)
Algorithme de marquage-collage (après recyclage)
L'avantage est que cela ne provoquera pas de fragmentation de la mémoire.
L'algorithme de copie doit d'abord diviser la mémoire en deux blocs, allouer d'abord de la mémoire sur l'un des blocs de mémoire, lorsque ce bloc de mémoire est alloué, un garbage collection est effectué, puis tous les objets survivants sont copiés dans un autre morceau de mémoire et le premier morceau de mémoire est effacé.
Algorithme de copie (avant recyclage)
Algorithme de copie (après recyclage)
Ceci Le L'algorithme ne produit pas de fragmentation de la mémoire, mais cela équivaut à utiliser seulement la moitié de l'espace mémoire. Dans le même temps, l'algorithme de réplication est lié au nombre d'objets survivants. Si le nombre d'objets survivants est important, l'efficacité de l'algorithme de réplication sera considérablement réduite.
Dans la machine virtuelle Java, le cycle de vie des objets peut être long ou court. Le cycle de vie de la plupart des objets est très court et seul un petit nombre d'objets le seront. être en mémoire. Il persiste longtemps, les objets peuvent donc être placés dans différentes zones en fonction de leur cycle de vie. Dans le tas de la machine virtuelle Java qui utilise l'algorithme de collecte générationnelle, il est généralement divisé en trois zones, utilisées respectivement pour stocker ces trois types d'objets :
Nouvelle génération - objets nouvellement créés, Dans Lorsque le code est en cours d'exécution, de nouveaux objets seront généralement créés en continu. Beaucoup de ces objets nouvellement créés sont des variables locales et deviendront bientôt des objets inutiles. Ces objets sont placés dans une zone de mémoire appelée la jeune génération. La nouvelle génération se caractérise par de nombreux objets poubelles et peu d’objets survivants.
Ancienne génération - certains objets ont été créés très tôt et n'ont pas été recyclés après plusieurs GC, mais ont toujours survécu. Ces objets sont placés dans une zone dite de l'ancienne génération. La caractéristique de l’ancienne génération est qu’il existe de nombreux objets survivants et peu d’objets poubelles.
Génération permanente - certains objets qui existent en permanence avec le cycle de vie de la machine virtuelle, comme certains objets statiques, constantes, etc. Ces objets sont placés dans une zone appelée génération permanente. La caractéristique de la génération permanente est que ces objets ne nécessitent généralement pas de garbage collection et survivront pendant l'exécution de la machine virtuelle. (Avant Java 1.7, les objets de génération permanente étaient stockés dans la zone de méthode. Les objets de génération permanente dans la zone de méthode Java 1.7 étaient déplacés vers le tas. Dans Java 1.8, la génération permanente a été supprimée du tas. Cette mémoire est la métaespace. )
L'algorithme de collecte générationnelle effectue également un garbage collection basé sur la nouvelle génération et l'ancienne génération.
Pour la zone nouvelle génération, beaucoup d'objets poubelles seront recyclés à chaque GC, et seuls quelques-uns survivront. Par conséquent, l'algorithme de recyclage de copie est utilisé et les quelques objets survivants restants peuvent être copiés pendant la GC.
Dans la zone nouvelle génération, la copie et le recyclage ne sont pas effectués selon le ratio de 1:1, mais divisés en trois zones : Eden, SurvivorA et SurvivorB selon le ratio de 8:1:1. . Parmi eux, Eden signifie le Jardin d'Eden, décrivant les nombreux nouveaux objets qui y sont créés ; la zone Survivant fait référence aux survivants, c'est-à-dire aux objets qui survivent encore après avoir expérimenté GC.
La zone Eden fournit une mémoire tas au monde extérieur. Lorsque la zone Eden est presque pleine, un GC mineur (New Generation GC) est effectué, les objets survivants sont placés dans la zone SurvivorA, et la zone Eden est dégagée
Après l'Eden ; la zone est effacée, elle continuera à être fournie au monde extérieur. Mémoire du tas
Lorsque la zone Eden est à nouveau remplie, un GC mineur (GC nouvelle génération) est effectué sur le Zone Eden et zone SurvivorA en même temps, et les objets survivants sont placés dans la zone SurvivorB et la zone SurvivorA en même temps
La zone Eden continue de fonctionner. fournit une mémoire de tas au monde extérieur et répète le processus ci-dessus, c'est-à-dire qu'une fois la zone Eden remplie, la zone Eden et une certaine zone Survivant. Les objets survivants sont placés dans une autre zone Survivant
GC_CONCURRENT : Lorsque la mémoire tas de notre application atteint une certaine quantité, ou peut être considérée comme étant presque pleine, le système déclenchera automatiquement une opération GC pour libérer la mémoire.
GC_EXPLICIT : Indique que le GC est déclenché lorsque l'application appelle l'interface System.gc, VMRuntime.gc ou reçoit le signal SIGUSR1.
GC_BEFORE_OOM : indique que le GC est déclenché par le dernier effort avant de se préparer à lever une exception MOO.
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!