web-dev-qa-db-fra.com

MaxTenuringThreshold - comment cela fonctionne-t-il exactement?

J'ai fait des recherches sur Google toute la journée à ce sujet. Mais ce n'est toujours pas clair pour moi, donc la question peut sembler un peu délirante.

Eh bien .. nous savons qu'il y a peu de domaines de mémoire principaux. Young, Tenured (Old gen) et PermGen.

Le domaine Young est divisé en Eden et Survivor (dont deux). OldGen est destiné aux objets survivants.
Concernant MaxTenuringThreshold - il empêche les objets d'être finalement copiés trop tôt dans l'espace OldGen.
C'est assez clair et compréhensible.

Mais ce "MaxTenuringThreshold" ... - comment ça marche exactement?
Comment le ramasse-miettes gère-t-il ces objets qui survivent encore jusqu'à MaxTenuringThreshold et de quelle manière? Où sont-ils situés?
Les objets sont recopiés dans les espaces Survivor pour la collecte des ordures .. ou cela se produit autrement?

Je n'ai trouvé aucune bonne explication à ce sujet, donc je serai très reconnaissant de tout lien ou explication utile.

30
VirtualVoid

Chaque objet dans Java a un en-tête qui est utilisé par l'algorithme Garbage Collection (GC). Le jeune collecteur d'espace (qui est responsable de la promotion des objets) utilise quelques bits de cet en-tête. pour suivre le nombre d'objets de collections qui ont survécu (la JVM 32 bits utilise 4 bits pour cela, 64 bits probablement un peu plus).

Lors de la collecte de jeunes espaces, chaque objet est copié. L'objet peut être copié dans l'un des espaces de survie (celui qui est vide avant le jeune GC) ou dans l'ancien espace. Pour chaque objet copié, l'algorithme GC augmente son âge (nombre de collections survécues) et si l'âge est supérieur au seuil de tenure actuel il serait copié ( promu) à l'ancien espace. L'objet pourrait également être copié directement dans l'ancien espace si l'espace de survie est plein (débordement).

Le voyage d'Object a le modèle suivant:

  • alloué en eden
  • copié de eden à l'espace de survie en raison du jeune GC
  • copié de l'espace de survie vers un (autre) espace de survie en raison du jeune GC (cela peut arriver plusieurs fois)
  • promu de la survie (ou de l'éden possible) à l'ancien espace en raison d'un jeune GC (ou GC complet)

le seuil de tenure réel est ajusté dynamiquement par la JVM, mais MaxTenuringThreshold lui fixe une limite supérieure.

Si vous définissez MaxTenuringThreshold = 0, tous les objets seront promus immédiatement.

J'ai quelques articles à propos de Java garbage collection, vous pouvez y trouver plus de détails.

59
Alexey Ragozin

(Avertissement: cela couvre HotSpot VM uniquement)

Comme le précise Alexey, le seuil de tenure réellement utilisé est déterminé dynamiquement par la JVM. Il y a très peu de valeur à le régler. Pour la plupart des applications, la valeur par défaut de 15 sera suffisamment élevée, car généralement plus d'objets survivent à la collection. Lorsque de nombreux objets survivent à la collection, les espaces des survivants débordent directement sur les anciens. C'est ce qu'on appelle une promotion prématurée et un indicateur d'un problème. Cependant, il peut rarement être résolu en réglant MaxTenuringThreshold.

Dans ces cas, SurvivorRatio peut parfois être utilisé pour augmenter l'espace dans les espaces des survivants, ce qui permet au régime de fonctionner réellement. Cependant, le plus souvent, agrandir la jeune génération est le seul bon choix (du point de vue de la configuration). Si vous recherchez du point de vue du codage, vous devez éviter une allocation excessive des objets pour permettre au mode de fonctionnement de fonctionner comme prévu.

Pour répondre exactement à ce que vous avez demandé: lorsqu'un objet atteint son seuil de tenure déterminé par la JVM, il est copié dans l'ancien. Avant cela, il sera copié dans l'espace de survivant vide. Les objets qui ont survécu pendant un certain temps mais qui sont dé-référencés avant d'atteindre le seuil sont nettoyés du survivant très efficacement.

14
Fabian Lange