Maison  >  Article  >  Java  >  Explication détaillée d'exemples de garbage collection en mode singleton en Java

Explication détaillée d'exemples de garbage collection en mode singleton en Java

黄舟
黄舟original
2017-08-08 10:25:341548parcourir

Cet article présente principalement en détail les informations pertinentes sur le garbage collection en mode singleton, qui ont une certaine valeur de référence. Les amis intéressés peuvent se référer à

Proposition de discussion : Quand un objet singleton ne l'est pas. utilisé depuis longtemps, sera-t-il recyclé par le mécanisme de garbage collection de la jvm ?

Tout d'abord, permettez-moi d'expliquer pourquoi cette question se pose. L'auteur n'a jamais envisagé l'impact du garbage collection sur le modèle singleton auparavant, jusqu'à ce que je lise un livre l'année dernière, "Zen of Design". Modèles" 》 par Qin Xiaobo. C'est mentionné dans le livre Dans les applications j2ee, le mécanisme de récupération de place jvm traitera les objets singleton qui n'ont pas été utilisés depuis longtemps comme des déchets et les recyclera lorsque le CPU est inactif. Les nombreux livres de modèles de conception que j'ai lus auparavant, y compris "Java and Patterns", ne mentionnaient pas l'impact du mécanisme de récupération de place jvm sur les singletons. Et pendant le processus de travail, je n'ai jamais eu l'expérience du recyclage d'objets singleton. De plus, de nombreux seniors au travail m'ont prévenu : essayez de ne pas déclarer trop de propriétés statiques, car ces propriétés statiques ne seront pas libérées après avoir été chargées. Par conséquent, je suis sceptique quant à l'affirmation selon laquelle le garbage collection JVM recyclera les objets singleton. Peu à peu, j'ai découvert que parmi mes collègues et le personnel technique sur Internet, il y avait fondamentalement deux factions opposées sur cette question. Alors, jvm recyclera-t-il les objets singleton qui n'ont pas été utilisés depuis longtemps ?

Concernant cette question, l'opinion personnelle de l'auteur est la suivante : ne sera pas recyclé .

Ce qui suit est mon code de test


class Singleton {
 private byte[] a = new byte[6*1024*1024];
 private static Singleton singleton = new Singleton();
 private Singleton(){}
 
 public static Singleton getInstance(){
 return singleton;
 }
}

class Obj {
 private byte[] a = new byte[3*1024*1024];
}

public class Client{
 public static void main(String[] args) throws Exception{
 Singleton.getInstance();
 while(true){
  new Obj();
 }
 }
}

Le but de ce programme est de simuler le conteneur j2ee, d'abord d'instancier Dans la classe Singleton, cette classe singleton occupe 6 Mo de mémoire, puis le programme entre dans une boucle infinie, créant constamment des objets, forçant le jvm à effectuer un garbage collection, puis à observer les informations de garbage collection si la mémoire est toujours supérieure à 6 Mo après. garbage collection, cela signifie que les objets Singleton ne seront pas recyclés.

La machine virtuelle utilisée pour exécuter ce programme est la machine virtuelle hotspot, qui est la machine virtuelle officiellement fournie par Java que nous utilisons le plus, communément appelée jdk, et la version est jdk1.6.0_12

Les paramètres des arguments de la machine virtuelle d'exécution sont : -verbose:gc -Xms20M -Xmx20M, ce qui signifie que les informations sur la mémoire sont affichées à chaque fois que la machine virtuelle effectue un ramasse-miettes et que la mémoire de la machine virtuelle est définie sur une valeur fixe. 20M.

Résultat en cours :

……
[Full GC 18566K->6278K(20352K), 0.0101066 secs]
[GC 18567K->18566K(20352K), 0.0001978 secs]
[Full GC 18566K->6278K(20352K), 0.0088229 secs]
……


À partir du résultat en cours, vous pouvez voir qu'il y a un total de 6M d'espace Non collecté. Par conséquent, l'auteur estime que, au moins dans la machine virtuelle hotspot, le garbage collection ne recyclera pas les objets singleton.

Plus tard, j'ai vérifié certaines informations pertinentes. L'algorithme de récupération de place de la machine virtuelle hotspot utilise l'algorithme de recherche racine. L'idée de base de cet algorithme est la suivante : pour tout objet "vivant", il doit éventuellement être retracé jusqu'à sa référence survivant dans la pile ou la zone de stockage statique. En utilisant une série de références nommées racines (GC Roots) comme point de départ, en partant de ces racines et en recherchant à travers une série de chemins, si l'objet dans le tas Java peut être atteint, alors l'objet est "vivant" et ne peut pas être recyclé. . Les objets pouvant être utilisés comme racines sont :

  •  Les objets référencés dans la pile de la machine virtuelle (table de variables locales dans le cadre de la pile).

  •  L'objet référencé par la propriété statique de classe dans la zone de méthode.

  •  L'objet référencé par la constante dans la zone méthode.

  •  L'objet référencé par JNI dans la pile de méthodes locale.

La zone méthode est une zone mémoire de la jvm, utilisée pour stocker les informations liées à la classe. Évidemment, l'objet créé par le mode singleton en Java est référencé par les propriétés statiques de sa propre classe, ce qui est conforme au deuxième article. Par conséquent, l'objet singleton ne sera pas récupéré par la JVM.

Bien que l'objet singleton dans le tas jvm ne soit pas récupéré, la classe singleton elle-même sera-t-elle collectée si elle n'est pas utilisée pendant une longue période ? Parce que jvm dispose également d'un mécanisme de récupération de place pour la zone de méthode. Si la classe singleton est collectée, alors les objets du tas perdront leur chemin vers la racine et seront inévitablement récupérés. À cet égard, l'auteur a vérifié la méthode de garbage collection de la zone de méthode de la machine virtuelle hotspot. Les conditions de jugement pour la classe de désinstallation jvm sont les suivantes :

  • . Toutes les instances de cette classe ont été recyclées. Autrement dit, il n'y a aucune instance de cette classe dans le tas Java.

  • Le ClassLoader qui a chargé cette classe a été recyclé.

  • L'objet java.lang.Class correspondant à cette classe n'est référencé nulle part, et les méthodes de cette classe ne sont accessibles par réflexion nulle part.

Ce n'est que lorsque les trois conditions sont remplies que la jvm déchargera la classe lors du ramasse-miettes. Évidemment, la classe singleton ne remplit pas la condition 1, donc la classe singleton ne sera pas déchargée. En d'autres termes, tant que la référence statique dans la classe singleton pointe vers l'objet singleton dans le tas jvm, alors la classe singleton et l'objet singleton ne seront pas récupérés. Selon l'algorithme de recherche racine, si l'objet sera un garbage collection. collecté ou non La durée d'utilisation n'a pas d'importance, cela dépend simplement du fait que l'objet soit "vivant". Si un objet n'a pas été utilisé depuis longtemps et est recyclé, alors l'algorithme de collecte doit être l'algorithme récemment inutilisé. L'algorithme récemment inutilisé est généralement utilisé dans l'échange de mémoire interne et externe du système d'exploitation. utilisé dans le garbage collection des machines virtuelles, ne serait-il pas trop dangereux ? Ce qui précède est l’opinion de l’auteur.

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn