web-dev-qa-db-fra.com

Dans Java les déchets d'espace de génération permanente sont-ils collectés?

J'ai lu que l'espace Perm gen (ou génération permanente) n'est pas récupéré. Cependant, dans la collection CMS, je peux voir certaines classes se décharger dans mon journal GC. Les déchets perm gen sont-ils donc collectés lors de la collecte complète ou de la collecte CMS?

36
Ashish

Le PermGen est une poubelle récupérée comme les autres parties du tas.

La chose à noter ici est que le PermGen contient des métadonnées des classes et des objets, c'est-à-dire des pointeurs dans le reste du tas où les objets sont alloués. Le PermGen contient également des chargeurs de classe qui doivent être détruits manuellement à la fin de leur utilisation, sinon ils restent en mémoire et conservent également des références à leurs objets sur le tas. L'article "Présentation de la génération permanente" de Jon Masamitsu sur le site du blog Sun/Oracle pourrait vous aider.

35
Sagar V

Dans les JVM de génération actuelle, permgen est en effet collecté comme les autres parties du tas. La page visualgc indique qu'elle est collectée avec l'ancienne génération.

Dans les anciennes machines virtuelles Java, cela n'était apparemment pas toujours le cas. Par exemple, dans Java 5 le collecteur CMS apparemment n'a pas collecté permGen par défaut: vous pouvez l'activer avec -XX:+CMSPermGenSweepingEnabled. Je me souviens également d'avoir entendu dire que certaines machines JVM très anciennes n'avaient pas du tout implémenté la collection permgen, bien que je ne trouve pas de source fiable pour ce ... ermm ... "factoid".

L'autre point, c'est que beaucoup de gens ont incorrectement attribué des exceptions "OutOfMemoryError: permgen" au permgen qui n'est pas collecté du tout. La réalité est différente. La cause la plus courante de ces OOME est un type insidieux de fuite de stockage qui se manifeste lorsque vous chargez du code à chaud dans une machine virtuelle Java en cours d'exécution. La fuite se produit car lorsqu'une instance d'une ancienne classe remplacée reste accessible. Cela rend la classe de l'objet accessible, ce qui rend le chargeur de classes accessible, ce qui fait que tous des anciennes classes sont accessibles, ainsi que leurs objets de code, leurs littéraux de chaîne et leur cadres statiques et statiques. Beaucoup de ces objets divulgués vivent dans l'espace permgen.


[~ # ~] mise à jour [~ # ~]

Depuis Java 8, permgen n'existe plus: élimination PermGen dans JDK 8

30
Stephen C