La Collecte des ordures et Fils

AFAIK quand un GC fait son truc, la machine virtuelle bloque tous les threads en cours d'exécution-ou du moins quand elle compacte le tas. Est-ce le cas dans les implémentations modernes du CLR et de la JVM (versions de Production à partir de janvier 2010) ? S " il vous plaît ne pas fournir des liens de base sur GC que je comprends le fonctionnement rudimentaire.

Je suppose que le verrouillage global est le cas car lorsque le compactage se produit, les références peuvent être invalides pendant la période de déplacement, et il semble plus simple de verrouiller l'ensemble tas (c'est-à-dire indirectement en bloquant tous les threads). Je peux imaginer des mécanismes plus robustes, mais KISS prévaut souvent.

Si je suis incorrect, ma question serait répondue par une simple explication de la stratégie utilisée pour minimiser le blocage. Si mon hypothèse est correcte, veuillez donner un aperçu des deux questions suivantes:

  1. Si tel est bien le comportement, comment les moteurs d'entreprise lourds comme JBoss et Glassfish maintiennent-ils un taux TPS élevé ? J'ai fait quelques googler sur JBOSS et je m'attendais à trouver quelque chose sur un Apache comme l'allocateur de mémoire adapté au traitement web.

  2. Face aux architectures numériques (potentiellement dans un avenir proche), cela ressemble à un désastre à moins que les processus ne soient liés par un thread et une allocation de mémoire.

21
demandé sur Joachim Sauer 2010-01-18 14:15:24

6 réponses

La réponse est que cela dépend des algorithmes de récupération de place utilisés. Dans certains cas, vous avez raison de dire que tous les threads sont arrêtés pendant GC. Dans d'autres cas, vous êtes incorrect dans le fait que la récupération de place se déroule pendant que les threads normaux sont en cours d'exécution. Pour comprendre comment les GC y parviennent, vous avez besoin d'une compréhension détaillée de la théorie et de la terminologie des éboueurs, combinée à une compréhension du collecteur spécifique. Il ne se prête tout simplement pas à un simple explication.

Oh oui, et il convient de souligner que de nombreux collectionneurs modernes n'ont pas de phase de compactage en soi. Ils fonctionnent plutôt en copiant des objets vivants dans un nouvel "espace" et en réduisant à zéro l'ancien "espace" lorsqu'ils sont terminés.

Si je suis incorrect, ma question serait répondue par une simple explication de la stratégie utilisée pour minimiser le blocage.

Si vous voulez vraiment comprendre comment éboueurs travail, je vous recommande:

... et méfiez-vous que trouver des descriptions précises, détaillées et publiques des internes des éboueurs de production n'est pas facile. (Bien que dans le cas des GC Hotspot, vous pouvez regarder le code source ...)

Modifier: dans réponse au Commentaire du PO ...

"Il semble que c'est comme je le pensais-il n'y a pas de moyen de contourner la partie "arrêter le monde"."

Ça dépend. Dans le cas du collecteur Concurrent Java 6 , Il y a deux pauses pendant le marquage des racines (y compris les piles), puis le marquage / copie d'autres objets se déroule en parallèle. Pour d'autres types de collecteurs simultanés, des barrières de lecture ou d'écriture sont utilisées pendant l'exécution du collecteur pour intercepter des situations où le collecteur et les threads d'application interféreraient autrement les uns avec les autres. Je n'ai pas ma copie de [Jones] ici en ce moment, mais je me souviens aussi qu'il est possible de rendre l'intervalle "stop the world" négligeable ... au prix d'opérations de pointeur plus coûteuses et / ou de ne pas collecter toutes les ordures.

16
répondu Stephen C 2015-06-04 22:18:26

Vous avez raison de dire que le garbage collector devra mettre en pause tous les threads de l'application. Ce temps de pause peut être réduit avec la JVM sun en utilisant le collecteur concurrent qui préformeune partie du travail sans arrêter l'application, mais il doit mettre en pause les threads de l'application.

Voir ici http://java.sun.com/javase/technologies/hotspot/gc/gc_tuning_6.html#par_gc et ici http://java.sun.com/javase/technologies/hotspot/gc/gc_tuning_6.html#cms pour détails sur la façon dont la JVM sun gère la collecte des ordures dans les dernières JVM.

Pour les applications web, Je ne pense pas que ce soit un problème. Comme les demandes de l'utilisateur doivent se terminer dans un petit laps de temps

Sur les applications TPS élevées, une stratégie courante consiste à exécuter plusieurs instances du serveur d'applications sur le même matériel ou sur un matériel séparé en utilisant l'affinité de session et le ballancement de charge. En faisant cela, la taille de tas individuelle par JVM est réduite, ce qui réduit les temps de pause pour GC lors de l'exécution d'une collection majeure. En général, la base de données devient le goulot de la bouteille plutôt que l'application ou la JVM.

Le plus proche que vous pourriez trouver au concept d'un web l'allocateur de mémoire spécifique dans in J2EE est un pool d'objets / instances effectué par les frameworks et les severs d'application. Par exemple, dans JBOSS, vous avez des pools EJB et des pools de connexion de base de données. Cependant, ces objets sont généralement regroupés en raison de leur coût de création élevé plutôt que de la surcharge de récupération de place.

2
répondu Aaron 2010-01-18 21:16:59

Je crois QU'IBM a effectué des recherches pour améliorer les performances du GC dans les systèmes multicœurs, ce qui inclut des travaux sur la réduction ou l'élimination du problème "tout arrêter".

Par exemple voir: un GC parallèle, incrémental et Concurrent pour les serveurs (pdf)

Ou google quelque chose comme "garbage collection simultanée ibm"

1
répondu redcalx 2010-01-18 13:02:26

AFAIK quand un GC fait son truc, la VM bloque tous les threads en cours d'exécution-ou du moins quand il compacte le tas. Est-ce le cas dans les implémentations modernes du CLR et de la JVM (versions de Production à partir de janvier 2010) ?

La JVM Hotspot de Sun et la CLR de Microsoft ont des GCs simultanés qui n'arrêtent le monde que pour de courtes phases (pour obtenir un instantané auto-cohérent des racines mondiales à partir desquelles toutes les données en direct sont accessibles) et non pour des cycles de collecte entiers. Je suis pas sûr de leurs implémentations de compactage mais c'est un événement très rare.

Si tel est bien le comportement, comment les moteurs d'entreprise lourds comme JBoss et Glassfish maintiennent-ils un taux TPS élevé?

La latence de ces moteurs est de plusieurs ordres de grandeur plus longue que le temps nécessaire pour arrêter le monde. En outre, les latences sont citées comme, par exemple, 95e percentile, ce qui signifie que la latence ne sera inférieure à la période entre guillemets que 95% du temps. Il est donc peu probable que les compactions affectent les latences citées.

1
répondu Jon Harrop 2010-08-17 13:41:11

Il existe un certain nombre d'algorithmes GC disponibles avec Java, qui ne bloquent pas tous les threads en cours d'exécution. Par exemple, vous pouvez utiliser-XX:+UseConcMarkSweepGC qui s'exécute simultanément avec l'application (pour la collecte de la génération tenured).

0
répondu Matthew Wilson 2010-01-18 11:49:11

L'état actuel de la collecte des ordures pour Java implique toujours des pauses occasionnelles "stop the world". Le G1 GC introduit sur Java 6u14 fait la plupart de son travail simultanément, cependant, lorsque la mémoire est vraiment faible, et il doit compacter le tas, alors il doit s'assurer que personne ne touche le tas en dessous. Cela exige que rien d'autre ne soit autorisé à procéder. Pour en savoir plus sur le GC G1, regardez les présentations de Sun .

0
répondu Paul Wagland 2010-01-18 12:48:47