Travailler avec des générations d'objets

Les ramasse-miettes Java implémentent une stratégie générationnelle de ramasse-miettes qui peut classer les objets par âge.

Un tel besoin (de marquer et de compacter tous les objets) dans la JVM peut être qualifié d'inefficace. Étant donné qu'un grand nombre d'objets sont alloués, leur liste s'allonge, ce qui entraîne une augmentation du temps de récupération de place. L'analyse empirique des applications a montré que la plupart des objets en Java sont de courte durée.

La zone de mémoire de tas dans la JVM est divisée en trois sections :

Travailler avec des générations d'objets

Jeune génération

Les objets nouvellement créés commencent dans la jeune génération. La jeune génération est subdivisée en deux catégories.

  • Eden Space - Tous les nouveaux objets commencent ici, ils se voient allouer de la mémoire initiale.
  • Espaces survivants (FromSpace et ToSpace) - Les objets sont déplacés ici depuis Eden après avoir survécu à un cycle de collecte des ordures.

Le processus lors duquel les objets sont ramassés par la jeune génération est appelé un événement mineur de ramasse-miettes.

Lorsque l'espace d'Eden est rempli d'objets, un petit ramasse-miettes est effectué. Tous les objets morts sont retirés et tous les objets vivants sont déplacés vers l'un des deux espaces restants. Le petit GC vérifie également les objets dans l'espace survivant et les déplace vers un autre (suivant) espace survivant.

Prenons la séquence suivante comme exemple.

  1. Il y a des objets des deux types (vivants et morts) dans Eden.
  2. Un petit GC se produit - tous les objets morts sont retirés d'Eden. Tous les objets vivants sont déplacés vers l'espace-1 (FromSpace). Eden et l'espace-2 sont maintenant vides.
  3. De nouveaux objets sont créés et ajoutés à Eden. Certains objets d'Eden et de l'espace-1 deviennent morts.
  4. Un petit GC se produit - tous les objets morts sont retirés d'Eden et de l'espace-1. Tous les objets vivants sont déplacés vers l'espace-2 (ToSpace). Eden et espace-1 sont vides.

Ainsi, à tout instant, une des cases survivantes est toujours vide. Lorsque les survivants atteignent un certain seuil pour se déplacer dans les espaces de survivants, ils passent à une génération plus âgée.

Vous pouvez utiliser l'indicateur -Xmn pour définir la taille de la jeune génération .

Ancienne génération

Les objets qui vivent une quantité de temps significative (par exemple, la majeure partie de la durée de vie d'un programme) finissent par devenir des objets plus anciens - des centenaires. Il est également connu sous le nom de génération régulière et contient des objets qui sont restés longtemps dans les espaces de survivants.

Le seuil de durée de vie d'un objet détermine le nombre de cycles de récupération de place qu'il doit effectuer avant d'être déplacé vers l'ancienne génération. Le processus lors duquel les objets sont envoyés à la poubelle depuis l'ancienne génération est appelé l'événement principal de récupération de place.

Vous pouvez utiliser les indicateurs -Xms et -Xmx pour définir la taille de mémoire de tas initiale et maximale .

Étant donné que Java utilise la récupération de place générationnelle, plus un objet subit d'événements de récupération de place, plus il se déplace sur le tas. Il commence dans la jeune génération et finit par se retrouver dans la génération régulière s'il vit assez longtemps.

Pour comprendre la valorisation des objets entre les espaces et les générations, considérons l'exemple suivant :

Lorsqu'un objet est créé, il est d'abord placé dans l'Eden de la jeune génération.

Dès qu'une petite collecte de déchets se produit, les objets vivants d'Eden sont déplacés vers FromSpace. Lors du prochain ramasse-miettes mineur, les objets vivants d'Eden et de l'espace sont déplacés vers ToSpace.

Ce cycle se répète un certain nombre de fois. Si l'objet est toujours "en service" après ce point, le prochain cycle de récupération de place le déplacera vers l'espace d'ancienne génération.

Génération permanente et métaspace

Les métadonnées comme les classes et les méthodes sont stockées dans la génération persistante. La JVM le remplit au moment de l'exécution en fonction des classes utilisées par l'application. Les classes qui ne sont plus utilisées peuvent passer de la génération permanente à la poubelle.

Vous pouvez utiliser les indicateurs -XX:PermGen et -XX:MaxPermGen pour définir la taille initiale et maximale de la génération permanente .

espace méta

Depuis Java 8, l'espace PermGen a été remplacé par l'espace mémoire MetaSpace. L'implémentation diffère de PermGen - cet espace de tas est maintenant modifié automatiquement.

Cela évite le problème de mémoire insuffisante de l'application qui se produit en raison de la taille limitée de l'espace de tas de PermGen. La mémoire du méta-espace peut être ramassée et les classes qui ne sont plus utilisées seront automatiquement nettoyées lorsque le méta-espace atteindra sa taille maximale.