Je remarque un phénomène étrange dans ma demande. Je stocke des objets dans un hashmap après les avoir soumis à un serveur et retirez-les lorsque la réponse arrive. p>
J'ai récemment remarqué des performances très lentes après avoir couru. Lors de la vérification, j'ai découvert que l'utilisation de la mémoire reste à 4 Go, puis tombe à moins de 1 Go. Je soupçonne qu'il nettoie beaucoup d'objets, c'est pourquoi la performance devient si mauvaise. P>
La question est-elle pourquoi elle prend pour Java aux ordures collectées si tard? C'est-à-dire pourquoi attendre que le tas soit plein puis faites-vous des ordures? Ne devrait-il pas collecter les ordures à intervalles réguliers. P>
Les objets qui sont stockés dans le hashmap sont créés à ce moment-là, c'est-à-dire qu'ils ne vivent pas depuis longtemps. P>
Ceci est sous Linux (RHEL), ORACLE JVM Hotspot 7. 64 bits. 4 cœurs. Voici comment l'application est exécutée: p>
Remarque: j'ai vu ceci: Réglage des collections à ordures pour une faible latence Mais pour l'instant, je veux comprendre pourquoi le GC prend si de si longtemps pour lancer? P> java -jar -xmx4g prog.jar code> p>
3 Réponses :
On dirait que vous avez l'une des deux questions suivantes: P>
Je regarderais à régler votre jeune génération pour être plus grand. Voir collection générationnelle des ordures et regardez les différents types de générations. p>
J'ai oublié d'ajouter: les objets qui sont stockés dans le hashmap sont créés à ce moment-là, c'est-à-dire qu'ils ne sont pas vécus depuis longtemps.
La question est-elle pourquoi elle prend pour Java aux ordures collectées si tard? C'est-à-dire pourquoi attendre que le tas soit plein puis faites-vous des ordures? Ne devrait-il pas collecter les ordures à intervalles réguliers. P> blockQuote>
Vous utilisez le collecteur de poubelles "Débit", et c'est ainsi que ce collecteur est conçu pour se comporter. Il vise à maximiser le débit du système en minimisant le pourcentage de temps de la CPU consacré à la collecte des ordures. Cela fait cela par la stratégie simple d'attendre que le tas (ou plus précisément, le nouvel espace d'objet) est plein. Toutes les choses étant égales, il est plus efficace de: p>
- Récupérez des ordures lorsque vous en avez beaucoup, et Li>
- Arrêtez tout le reste pendant vos ordures. li> ul>
(Pour comprendre pourquoi, vous devez comprendre les détails techniques de la copie de collectionneurs ...) p>
Bien sûr, cela signifie que vous obtenez des pauses significatives. P>
Si vous voulez une faible latence, vous devez utiliser un collecteur différent. Toutefois, cela se traduit par un pourcentage plus élevé de temps de processeur réel étant dépensé sur la collecte des ordures ... et d'autres frais généraux liés au GC. P>
Si vous obtenez beaucoup de pauses importantes, il peut également y avoir un problème avec la taille relative des espaces. Mais avant de jouer avec les paramètres associés, il vous sera conseillé d'activer la journalisation de GC pour essayer d'obtenir une poignée sur ce qui cause les pauses et à quel point ils sont fréquents. P>
C'est simplement parce que le GC par défaut ne démarre pas à moins que le tas est plein. P>
Le collecteur de déchets par défaut sélectionné par le JVM est le GC parallèle. Ses objectifs sont de libérer autant de mémoire que possible lors de la pause la plus courte possible. Cela ne commencera pas dans la jeune génération à moins que Eden soit plein. De même, cela ne commencera pas dans la vieille génération à moins que le tenu soit plein. P>
Vous pouvez passer à CMS si vous souhaitez nettoyer régulièrement la mémoire. Utilisez simplement le drapeau Donc, pour résumer: p>
GC parallèle pause l'application, ne commence que lorsqu'il n'y a pas d'autre choix P> LI>
CMS fonctionne simultanément sans pause de votre application, a des frais généraux p> li>
ul>
Source: http://www.oracle. Com / TechNetwork / Java / Javase / GC-Tuning-6-140523.html P> -xx: + USECONCMARKSWEPGC code>. Cependant, cela impliquera des frais généraux sur votre application. C'est le coût d'un GC qui fonctionne à intervalles réguliers sans faire une pause de votre application. P>
Avec quels drapeaux utilisez-vous le programme?
Fondamentalement, GC ne commence pas tant que le tas devient presque plein. Les déclencheurs précis varient en fonction de la version et des paramètres JVM, mais il est généralement plus efficace de faire un grand GC rarement vs beaucoup de plus petits. Cependant, comme vous l'avez noté, ce n'est pas idéal pour la latence. Si vous souhaitez une latence minimale, vous devez syntoniser. (Ou trouver l'une des rares implémentations de GC simultanées disponibles.)
@FDInoff Aucun indicateur autre que les valeurs par défaut. Fondamentalement, Java -Jar Prog.jar.
Vous dites essentiellement la valeur par défaut, mais vous indiquez que vous utilisez
-xmx code> qui n'est pas par défaut. Quels sont les drapeaux que vous passez à la JVM.@Fdinoff this: java -jar -xmx4g prog.jar
Jetez un coup d'œil au collecteur G1 de Java 7