La collecte des déchets JVM cible principalement le tas Garbage dans la pile, car l'espace est alloué dans la pile au démarrage du thread et lorsque le thread se termine, l'espace est automatiquement libéré et aucune surveillance en temps réel n'est requise ; sont généralement valables pendant toute la durée d'exécution du programme et il n'est pas nécessaire d'objets recyclés.
Les déchets font référence à des objets auxquels les threads ne peuvent pas accéder. Un objet ne peut être utilisé que s'il est visible par le thread et peut également être simplement compris. comme un objet sans aucune référence. À proprement parler, l'expression sans aucune référence à un objet réduit la portée des déchets. Par exemple, dans une référence circulaire, un objet A fait référence à un autre objet B, et l'objet B fait référence à A, et les références de A et B La relation. n'existe qu'entre les deux. Si aucun objet externe ne fait référence à A ou B, alors A et B ne peuvent pas être inclus dans l'exécution du programme, c'est-à-dire qu'ils ne sont accessibles par aucun thread et deviennent des objets inutiles selon le. définition des déchets Motivation, les objets qui ne sont plus utilisés sont des déchets, et A et B appartiennent naturellement aux déchets.
Parfois, les déchets sont également appelés objets inutiles, et les non-déchets sont appelés objets vivants.
2. Fuite de mémoire
Un objet est créé dans la méthode. Le but de la création de l'objet est uniquement d'accéder à la méthode doSome dans l'objet. Une fois l'accès à la méthode effectué, l'objet ne sera plus accessible à ce moment. La variable de référence obj pointe toujours vers l'objet. Puisque l'objet S'il y a une référence, l'objet ne sera pas considéré comme un déchet, mais l'objet est devenu un objet inutile et doit être déréférencé afin que le ramasse-miettes puisse récupérer l'espace mémoire occupé. par l'objet "obj=null;"
Le garbage collector ne recycle pas les objets, mais l'espace mémoire occupé par les objets inutiles afin que l'espace puisse être recyclé Utiliser à nouveau.
Espace libre plus petit et discontinu généré lors du processus d'allocation de mémoire et de recyclage, comme le montre la figure Affichage :
L'espace en attente d'être recyclé étant dispersé, une fois le recyclage terminé, l'espace disponible est divisé en un par l'espace utilisé. Étant donné que ces unités sont petites et ne peuvent pas stocker de données volumineuses, un espace supplémentaire doit être ouvert pour les données volumineuses, ce qui entraîne un gaspillage de mémoire.
donné lorsque l'objet est créé L'objet ajoute un compteur de référence Chaque fois qu'une variable fait référence à l'objet, le compteur est incrémenté de 1. Lorsque la variable libère la référence, le compteur est décrémenté de 1. Si le compteur est à 0 à tout moment, cela signifie que aucun objet ne fait référence à l'objet et l'objet devient un déchet.
Le défaut inhérent de l'algorithme de comptage de références est qu'il ne peut pas résoudre le problème des références circulaires, c'est-à-dire que même si les deux objets de la référence circulaire ne sont plus utilisés, ils le sont toujours considérés comme des objets utilisables et ne seront pas des déchets recyclés par le recycleur. Le mécanisme de récupération de place JVM n'utilise pas cet algorithme, mais l'algorithme d'analyse d'accessibilité suivant.
L'algorithme d'analyse d'accessibilité utilise le suivi pour déterminer si l'objet est vivant. Les objets atteints sont tous des objets vivants, et les objets introuvables ou inaccessibles sont des objets inutiles. Le point de départ du suivi est tout objet auquel on accède actuellement. À partir de cet objet, recherchez l'objet référencé par l'objet et effectuez une boucle en séquence pour former une chaîne de référence. Les objets qui ne sont pas sur la chaîne de référence sont des objets qui ne le sont pas. utilisé par le thread et sont des déchets. Comme le montre la figure ci-dessous, une chaîne de référence est formée sur le côté gauche.Tous les objets de la chaîne sont des objets vivants. Bien que les objets du côté droit aient des relations de référence les uns avec les autres, ils sont hors de la chaîne de référence du fil. , ce sont donc des objets inutiles.
Cette analyse est dynamique, non statique, et change à mesure que la relation de référence d'objet change.
Différents objets ont des cycles de vie différents Afin de recycler la mémoire en temps opportun, la récupération de place est fréquemment effectuée. sur les objets avec des cycles de vie courts. Les opérations et les objets avec des cycles de vie longs sont relativement stables et peuvent exister pendant une longue période. Par conséquent, afin de réduire les coûts et le nombre de garbage collection, les objets avec des cycles de vie différents sont stockés dans différentes zones de la mémoire afin d'utiliser différentes méthodes de garbage collection.
JVM divise l'espace de stockage d'objets en trois zones : nouvelle génération, ancienne génération et génération permanente.
La nouvelle génération est créée pour recycler rapidement les objets ayant des cycles de vie courts. Tous les objets nouvellement générés sont d'abord placés dans. la nouvelle génération. La nouvelle génération est divisée en trois parties : Eden, du survivant et au survivant, avec un rapport spatial de 8 :1 :1.
Les objets nouvellement créés sont d'abord placés dans l'Eden, et plusieurs gc (garbage collection) sont effectués une fois la zone de l'Eden pleine, ces objets. sont toujours en vie Seront transférés vers la zone du survivant. Lorsque la zone du survivant est pleine, les objets survivants sont transférés vers la zone du survivant. Lorsque la zone du survivant est pleine, les objets survivants sont promus à l'ancienne génération.
JVM effectue fréquemment du gc sur les objets de la jeune génération. La plupart des objets seront recyclés dans la jeune génération, et un petit nombre entrera dans l'ancienne génération.
Les objets de l'ancienne génération sont tous des objets qui ont survécu à plusieurs GC et ont un cycle de vie plus long et stable. , donc moins d'opérations gc sont effectuées.
La génération permanente est la zone méthode Elle stocke les informations de classe, les variables statiques et les constantes. application, et n’est généralement pas nécessaire. Le garbage collector le gère.
L'algorithme de collecte des déchets est l'algorithme utilisé pour la collecte réelle après la confirmation des déchets. Il existe trois algorithmes courants :
Marquez d'abord les objets inutiles, puis récupérez l'espace mémoire occupé par les objets, ce qui mènera à la mémoire. fragmentation et n’est fondamentalement pas utilisé l’algorithme.
Divisez l'espace mémoire en plusieurs zones Lors du garbage collection, tous les objets survivants dans une zone sont copiés dans une autre. zone, puis effacez cette zone afin qu’il n’y ait pas de fragmentation de la mémoire. Cet algorithme est utilisé lors du garbage collection de nouvelle génération, en copiant de la zone eden vers la zone du survivant, puis vers la zone vers le survivant. Comme il y a moins d'objets survivants, moins d'espace est occupé lors de la copie.
Marquez d'abord les objets qui doivent être effacés, déplacez tous les objets survivants vers une extrémité, puis effacer tous les objets inutiles. Contrairement à la nouvelle génération, l'ancienne génération a plus d'objets survivants après chaque GC, et l'algorithme de copie occupe beaucoup de mémoire. L'algorithme « marquer-organiser » économise de la mémoire sans provoquer de fragmentation de la mémoire.
Différentes générations ont des mécanismes gc différents : Scavenge GC et Full GC.
Lorsque la zone eden de nouvelle génération est pleine et que les objets nouvellement générés ne parviennent pas à demander de l'espace, Scavenge GC sera déclenché pour effectuer une manipulation gc sur la zone eden, effacer inutile objets et libérer de l'espace. Scavenge GC ne fonctionne que sur la nouvelle génération.
Lorsque l'ancienne génération est pleine ou que la génération persistante est pleine, ou que la méthode System.gc() est explicitement appelée, Full GC sera déclenché pour effectuer gc sur toutes les zones de stockage d'objets , consommant des ressources. Plus grand, il devrait y avoir moins de temps de GC complet.
Informer la JVM de start garbage Le collecteur et le garbage collector utilisent des threads démons et ne démarrent pas nécessairement immédiatement. L'heure précise à laquelle ils démarrent ne peut pas être contrôlée. De plus, consomme beaucoup de ressources, donc ne l'appelez généralement pas explicitement.
Méthode de portée d'objet. Appelé après que la JVM ait confirmé qu'un objet n'est pas accessible, il ne peut être appelé qu'une seule fois et est généralement utilisé pour libérer des ressources de connexion. Une fois cette méthode appelée, le garbage collector ne récupérera pas immédiatement l'espace occupé par l'objet, car l'objet est accessible à nouveau lors de l'exécution de cette méthode. Au lieu de cela, il ne récupérera l'espace occupé par l'objet qu'après avoir confirmé que l'objet est utilisé. l'objet est toujours inaccessible lors du prochain espace gc.
Évitez d'utiliser des variables statiques, car le cycle de vie des variables statiques est différent de celui de l'application De même, même s'il n'est pas utilisé pendant une longue période, il occupe toujours de l'espace mémoire.
Les connexions aux ressources, telles que OutputStreamInputStreamConnectionSocket, doivent être fermées immédiatement après utilisation et les ressources libérées en temps opportun.
Essayez de ne pas appeler explicitement System.gc(), car cette méthode peut déclencher Full GC, ce qui coûte cher.
Réduisez l'utilisation de variables temporaires, car une fois la méthode exécutée, les variables temporaires deviennent des déchets. Un grand nombre de variables temporaires augmenteront le nombre de gc. et augmenter la consommation du système.
Une fois l'objet référencé, libérez la référence dans le temps pour récupérer l'espace mémoire dans le temps.
Utilisez autant que possible des objets mutables et réduisez le nombre d'utilisations d'objets immuables.
Essayez d'utiliser des variables de type de base au lieu des classes wrapper correspondantes, car les variables de type de base occupent beaucoup moins de ressources que les classes wrapper correspondantes.
Créer et supprimer des objets de manière dispersée. Étant donné que la création d'objets ensemble nécessite beaucoup d'espace, Full GC est susceptible d'être déclenché, augmentant instantanément la consommation du système. La suppression intensive d'objets peut provoquer l'apparition d'un grand nombre d'objets inutiles en un instant, ce qui peut également déclencher le Full GC.
Référence :
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!