1. Modèle de mémoire Java
Lors de l'exécution d'un programme, la machine virtuelle Java divise la mémoire qu'elle gère en plusieurs domaines de données. La distribution de ces zones de données est indiquée dans la figure ci-dessous:
Compteur du programme: une petite zone de mémoire pointant vers le bytecode actuellement exécuté. Si le thread exécute une méthode Java, ce compteur enregistre l'adresse de l'instruction de bytecode de machine virtuelle en cours d'exécution. Si la méthode native est exécutée, la valeur de la calculatrice est vide.
Java Virtual Machine Stack: Les threads sont privés et leur cycle de vie est cohérent avec les fils. Lorsque chaque méthode est exécutée, une trame de pile sera créée pour stocker des informations telles que les tables de variables locales, les piles d'opérande, les liens dynamiques, les sorties de méthode, etc.
Pile de méthode locale: les fonctions sont similaires à la pile de machines virtuelles, sauf que la pile de machine virtuelle effectue des services de méthode Java pour la machine virtuelle, tandis que la pile de méthode locale sert la méthode native utilisée.
Java Heap: Il s'agit du plus grand morceau de mémoire de gestion de la machine virtuelle, partagée par tous les threads, cette zone est utilisée pour stocker des instances d'objets, et presque tous les objets sont alloués dans ce domaine. Le tas Java est la zone principale du recyclage de la mémoire. Du point de vue du recyclage de la mémoire, car la plupart des collectionneurs actuels utilisent des algorithmes de collecte générationnelle, le tas Java peut également être subdivisé en: la nouvelle génération et l'ancienne génération. Si un peu subdivisé, il peut être divisé en espace eden, de l'espace de survivant à l'espace de survivant, etc. Selon la spécification de la machine virtuelle Java, le tas Java peut être dans un espace physiquement discontinue, tant qu'il est logiquement continu.
Zone de méthode: Comme Java, il est partagé par divers threads et est utilisé pour stocker des données telles que les informations de classe qui ont été chargées par la machine virtuelle, toujours activée, les variables statiques, le code compilé par le compilateur instantané.
Pool constant d'exécution, le pool constant d'exécution fait partie de la zone de méthode. En plus de la version de classe, des champs, des méthodes, des interfaces et d'autres informations de description, il existe également un pool constant dans le fichier de classe, qui est utilisé pour stocker diverses références littérales et symboliques générées pendant la période de compilation. Pendant l'exécution, de nouvelles constantes peuvent être placées dans la piscine constante. Le plus couramment utilisé est la méthode inter () de la classe de chaîne. Lorsqu'une instance de chaîne appelle Internal, Java découvre s'il existe les mêmes constantes de chaîne Unicode dans le pool constant. S'il y en a, il renvoie sa référence; Sinon, ajoutez un Unicode égal à la chaîne d'instance et renvoie sa référence.
2. Comment déterminer l'objet à ordures
Il y a plusieurs instances d'objet stockées dans le tas Java. Avant que le collecteur des ordures ne recycle le tas, il doit d'abord déterminer quels objets sont toujours "vivants" et qui ont "mort", c'est-à-dire des objets qui ne seront en aucun cas utilisés.
CITATION DE CITATION
La méthode de comptage des citations est simple à implémenter et efficacement, et est un bon algorithme dans la plupart des cas. Le principe est: ajouter un compteur de référence à l'objet. Chaque fois qu'il y a un endroit pour référence à l'objet, le compteur est augmenté de 1. Lorsque la référence échoue, le compteur est réduit de 1. Lorsque la valeur du compteur est 0, cela signifie que l'objet n'est plus utilisé. Il convient de noter que la méthode de comptage de référence est difficile pour résoudre le problème de la référence mutuelle entre les objets, et les machines virtuelles Java traditionnelles n'utilisent pas la méthode de comptage de référence pour gérer la mémoire.
Algorithme d'analyse d'accessibilité
L'idée de base de cet algorithme est de rechercher vers le bas à travers une série d'objets appelés "Roots GC" comme point de départ, à partir de ces nœuds. Le chemin fouillé est appelé une chaîne de référence. Lorsqu'un objet n'est pas connecté à des racines GC sans aucune chaîne de référence (dans les mots de la théorie des graphiques, il est des racines GC à cet objet qui est inaccessible), il est prouvé que cet objet n'est pas disponible. Comme le montre la figure, bien que les objets 5, l'objet 6 et l'objet 7 soient liés les uns aux autres, ils sont inaccessibles pour les racines GC, ils seront donc jugés comme des objets recyclables.
En langue java, les objets suivants qui peuvent être utilisés comme racines GC incluent:
Objet référencé dans la pile de machines virtuelles (table de variable locale dans le cadre de pile).
Objet référencé par l'attribut statique de la classe dans la zone de méthode.
Objet référencé par les constantes dans la zone de la méthode.
Objets référencés par JNI (c'est-à-dire la méthode native générale) dans la pile de méthode locale.
Maintenant, la question est: l'algorithme d'analyse d'accessibilité aura-t-il un problème de référence circulaire entre les objets? La réponse est oui, c'est-à-dire qu'il n'y aura pas de problème de référence circulaire entre les objets. GC Root est un "point de départ" spécialement défini en dehors du graphique de l'objet et ne peut pas être référencé par des objets dans le graphique d'objet.
Mourir ou ne pas mourir
Même les objets inaccessibles dans l'algorithme d'analyse d'accessibilité ne sont pas "doivent mourir". À l'heure actuelle, ils sont temporairement au stade de la "probation". Pour déclarer vraiment un objet mort, il doit passer par au moins deux processus de marquage: si l'objet constate qu'il n'y a pas de chaîne de référence connectée aux racines GC après avoir effectué une analyse d'accessibilité, il sera marqué pour la première fois et filtré. La condition de filtrage est de savoir s'il est nécessaire que cet objet exécute la méthode finapze (). Lorsque l'objet ne remplace pas la méthode finapze () ou que la méthode finapze () a été appelée par la machine virtuelle, la machine virtuelle considère les deux cas comme "pas besoin d'exécuter". Dans le programme, vous pouvez écraser Finapze () pour créer un processus d'auto-salvation "passionnant", mais ce n'est qu'une chance.
/ ** * Ce code démontre deux points: * 1. Les objets peuvent se sauver lorsqu'ils sont GC. * 2. Il n'y a qu'une seule chance de s'auto-résoudre, car la méthode Finapze () d'un objet ne sera automatiquement appelée une fois par le système au plus * @author zzm * / pubpc class FinapzeesCapegc {pubpc static finapzeescapegc save_hook = null; PubPc void Isapve () {System.out.println ("Oui, je suis toujours apve :)"); } @Override Protected void finapze () lève le throwable {super.finapze (); System.out.println ("Finapze Mehtod exécuté!"); Finapzeescapegc.save_hook = this; } PubPc static void main (String [] args) lève le throwable {Save_Hook = new FinapzeesCapeGC (); // L'objet se sauve avec succès pour la première fois Save_Hook = null; System.gc (); // Parce que la méthode Finapze a une faible priorité, faites une pause pendant 0,5 seconde pour l'attendre thread.Sleep (500); if (save_hook! = null) {Save_Hook.isapve (); } else {System.out.println ("Non, je suis mort :(");} // Le code suivant est exactement le même que celui ci-dessus, mais cette fois, la méthode d'auto-résolution. Save_hook.isapve ();} else {System.out.println ("Non, je suis mort :(");}}}Le résultat en cours est:
Finapze Mehtod a exécuté! Oui, je suis toujours apve :) Non, je suis mort :(
Parlons des citations
Qu'il s'agisse de juger le nombre de références d'un objet via un algorithme de comptage de référence ou de déterminer si la chaîne de référence de l'objet est accessible via un algorithme d'analyse d'accessibilité, déterminant si la survie de l'objet est liée à la "référence". Avant JDK 1.2, la définition des références en Java était très traditionnelle: si la valeur stockée dans les données de type de référence représente l'adresse de départ d'un autre morceau de mémoire, il est dit que ce morceau de mémoire représente une référence. Après JDK 1.2, Java a élargi le concept de référence et a divisé les références en quatre types: référence forte, référence douce, référence faible et référence fantôme. La force de ces quatre types de référence s'est progressivement affaiblie à son tour.
• La citation forte fait référence aux références courantes dans le code du programme, telles que "objet obj = nouveau objet ()". Tant que la forte citation existe toujours, le collecteur des ordures ne recyclera jamais l'objet référencé.
• Des références douces sont utilisées pour décrire certains objets utiles mais pas nécessaires. Pour les objets associés à référence douce, ces objets seront répertoriés dans la portée de recyclage pour un deuxième recyclage avant que le système ne soit sur le point d'avoir une exception de débordement de mémoire. S'il n'y a pas assez de mémoire pour ce recyclage, une exception de débordement de mémoire sera lancée. Après JDK 1.2, la classe Softreference est fournie pour implémenter des références Soft.
• Des références faibles sont également utilisées pour décrire des objets non essentiels, mais leur force est plus faible que les références douces. Les objets associés à des références faibles ne peuvent survivre que jusqu'à ce que la prochaine collection de déchets se produise. Lorsque le collecteur des ordures fonctionne, les objets qui ne sont associés qu'aux références faibles sont collectés, que la mémoire actuelle soit suffisante. Après JDK 1.2, la classe de référence faible est fournie pour mettre en œuvre des références faibles.
• Les citations vides sont également appelées citations fantômes ou citations fantômes, et elles sont la relation de citation la plus faible. La question de savoir si un objet a une référence virtuelle n'aura aucun impact sur son temps de survie, il ne sera pas possible d'obtenir une instance d'objet via une référence virtuelle. Le seul but de la mise en place d'associations de référence virtuelle pour un objet est de recevoir une notification système lorsque l'objet est recyclé par le collecteur. Après JDK 1.2, la classe Phantomreference est fournie pour implémenter des références virtuelles.
Exemple d'utilisation de référence douce:
package jvm; import java.lang.ref.softreference; class node {pubpc string msg = "";} pubpc class hello {pubpc static void main (string [] args) {node node1 = new node (); // Strong Reference Node1.msg = "Node1"; Softreference <Node> Node2 = new Softreference <Node> (Node1); // Soft Reference node2.get (). Msg = "node2"; System.out.println (node1.msg); System.out.println (node2.get (). Msg);}}Le résultat de la sortie est:
node2Node2
3. Algorithme de collecte de déchets typique
1.Lek-sweep (Mark-Clear) Algorithme
Il s'agit de l'algorithme de collecte des ordures le plus basique. La raison pour laquelle il est dit la plus fondamentale est qu'il est le plus facile à mettre en œuvre et l'idée la plus simple. L'algorithme de compensation de marque est divisé en deux étapes: l'étape de marquage et l'étape de compensation. La tâche de l'étape de marquage est de marquer tous les objets qui doivent être recyclés, et l'étape de compensation consiste à recycler l'espace occupé par les objets marqués. Le processus spécifique est illustré dans la figure ci-dessous:
Il peut être facilement vu à partir de la figure que l'algorithme de compensation de marque est plus facile à mettre en œuvre, mais il y a un problème sérieux qu'il est facile de générer des fragments de mémoire. Trop de fragments peuvent entraîner l'incapacité de trouver suffisamment d'espace lors de l'allocation d'espace pour les grands objets dans le processus ultérieur et de déclencher une nouvelle action de collecte des ordures à l'avance.
2. Copie d'algorithme
Afin de résoudre les lacunes de l'algorithme Mark-Sweep, l'algorithme de copie a été proposé. Il divise la mémoire disponible en deux morceaux de taille égale par capacité, en utilisant un seul morceau à la fois. Lorsque ce morceau de mémoire est utilisé, copiez l'objet encore vivant à une autre pièce, puis nettoyez l'espace mémoire utilisé à la fois, afin que les problèmes de fragmentation de la mémoire ne se produisent pas. Le processus spécifique est illustré dans la figure ci-dessous:
Bien que cet algorithme soit simple à implémenter, efficace à exécuter et pas facile à générer une fragmentation de la mémoire, il est coûteux d'utiliser l'espace mémoire car la mémoire qui peut être utilisée est réduite à la moitié de celle d'origine.
De toute évidence, l'efficacité de l'algorithme de copie a beaucoup à voir avec le nombre d'objets survivants. S'il y a beaucoup d'objets survivants, l'efficacité de l'algorithme de copie sera considérablement réduite.
3. Algorithme Mark-Compact (Mark-Collation)
Afin de résoudre les lacunes de l'algorithme de copie et d'utiliser pleinement l'espace mémoire, l'algorithme de compact Mark est proposé. L'algorithme marque la même chose que Mark-Sweep, mais après avoir terminé la marque, il ne nettoie pas directement les objets recyclables, mais déplace tous les objets vivants à une extrémité, puis nettoie la mémoire à l'extérieur de la limite d'extrémité. Le processus spécifique est illustré dans la figure ci-dessous:
4. Algorithme de collecte générationnelle
L'algorithme de collecte de génération est actuellement utilisé par la plupart des collectionneurs JVM Garbage. Son idée principale est de diviser la mémoire en plusieurs régions différentes selon le cycle de vie de la survie de l'objet. D'une manière générale, la zone de tas est divisée en l'ancienne génération et la jeune génération. La caractéristique de l'ancienne génération est que seul un petit nombre d'objets doivent être recyclés chaque fois que les ordures sont collectées, tandis que la caractéristique de la nouvelle génération est qu'un grand nombre d'objets doivent être recyclés chaque fois que les ordures sont collectées. L'algorithme de collecte le plus approprié peut alors être adopté en fonction des caractéristiques des différentes générations.
À l'heure actuelle, la plupart des collectionneurs d'ordures adoptent l'algorithme de copie pour la nouvelle génération, car dans la nouvelle génération, la plupart des objets doivent être recyclés à chaque fois, c'est-à-dire que le nombre d'opérations qui doivent être copiés sont petits, mais en réalité, l'espace de la nouvelle génération n'est pas divisé selon un ratio de 1: 1. D'une manière générale, la nouvelle génération est divisée en un plus grand espace Eden et deux plus petits espaces de survivants (généralement 8: 1: 1). Chaque fois que l'espace Eden et l'un des espaces de survivant sont utilisés, lors du recyclage, les objets qui survivent encore à Eden et survivant sont copiés dans un autre espace de survivant, puis Eden et les espaces de survivants qui viennent d'être utilisés sont nettoyés.
Parce que la vieillesse est que seul un petit nombre d'objets sont recyclés à chaque fois, l'algorithme de compact Mark est généralement utilisé.
La brève analyse ci-dessus du modèle de mémoire Java et de la collection d'ordures est tout le contenu que je partage avec vous. J'espère que vous pourrez vous faire référence et j'espère que vous pourrez soutenir Wulin.com plus.