46 votes

Qu'est-ce qui fait du déploiement à chaud un "problème difficile"?

Au travail, nous avons eu un problème avec "PermGen de mémoire" des exceptions, avec le chef de l'équipe de décider que c'était un bug dans la JVM - chose lié à la chaud-de déploiement de code. Sans expliquer beaucoup de détails, il a souligné que le déploiement à chaud est un "problème difficile", tellement fort que même .NET ne le font pas encore.

J'ai trouvé beaucoup d'articles expliquant le déploiement à chaud de l'oiseau-oeil-vue, mais toujours dépourvues de détails techniques. Quelqu'un pourrait-il m'indiquer une explication technique, et d'expliquer pourquoi le déploiement à chaud est un "problème difficile"?

60voto

Eddie Points 27755

Quand une classe est chargée, diverses données statiques de la classe est stockée dans PermGen. Tant sous la forme d'une référence à la présente instance de Classe existe, l'instance de classe ne peut pas être nettoyée.

Je crois qu'une partie du problème a à faire avec si ou pas le GC doit supprimer les anciennes instances de Classe de perm gen, ou pas. Généralement, chaque fois que vous déploiement à chaud, de nouvelles instances de classe sont ajoutés à la PermGen pool de mémoire, et la vieille, désormais inutilisée, ne sont pas supprimés. Par défaut, la Jvm Sun ne sera pas exécuté, la collecte des ordures dans la PermGen, mais ce peut être activé avec l'option "java" arguments de la commande.

Par conséquent, si vous avez chaud déployer suffisamment de fois, vous allez finir par épuiser votre PermGen space.

Si votre application web ne permet pas d'arrêter complètement lorsque déployée. -- si elle laisse un Thread en cours d'exécution, par exemple, alors toutes les instances de classes utilisées par l'application web sera épinglé dans le PermGen space. Vous redéployer et ont maintenant une autre copie intégrale de l'ensemble de ces instances de Classe chargé dans la PermGen. Vous annulez le déploiement et le Fil continue, l'épinglage d'un AUTRE ensemble d'instances de la classe dans PermGen. Vous redéployer et de la charge d'un ensemble de net jeu de copies... et éventuellement de votre PermGen se remplit.

Vous pouvez parfois résoudre ce problème en:

  • Fournissant des arguments de la commande à une récente JVM de Sun pour activer la GC dans le PermGen et de classes. Qui est: -XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled
  • En utilisant une autre machine qui n'emploient pas un fixe de taille moyenne PermGen ou qui n'GC sur les classes chargées,

Mais cela aidera seulement si votre web app s'arrête complètement et proprement, sans laisser de vivre des références à l'une des instances de Classe de Classe chargée par la Classe chargeurs pour que la Web App.

Même cela ne va pas nécessairement de résoudre le problème, en raison de chargeur de classe de fuites. (Ainsi que de trop nombreux internés des chaînes dans certains cas.)

Consultez les liens suivants pour plus d' (les deux en gras ceux qui ont des diagrammes de nice pour illustrer une partie du problème).

6voto

OscarRyz Points 82553

En général, le problème est le modèle de sécurité de Java qui tente d'éviter qu'une classe qui a déjà été chargé d'être à nouveau chargé.

De cours Java depuis le début, a pris en charge dynamique de chargement de classe, ce que c'est difficile, c'est la classe re-chargement.

Il a été d'étudier les nuisibles ( et pour une bonne raison ) que l'exécution d'une application java ai injecté avec une nouvelle classe avec un code malveillant. Par exemple, java.lang.String fendu la mise en œuvre à venir de l'internet , au lieu de créer de la chaîne, supprime certains de fichier aléatoire lors de l'invocation de la méthode length().

Donc, la manière de Java a été conçu ( et je présume .NET CLR en conséquence, parce que c'était très "inspiré" dans la JVM ) était à éviter, déjà chargé de la classe à charger de nouveau la même VM.

Ils ont offert un mécanisme de remplacer cette "fonctionnalité". Les chargeurs de classe, mais encore une fois les règles de la classe chargeurs, ils doivent demander la permission à la "mère" du chargeur de classe avant d'essayer de charger une nouvelle classe, si le parent a déjà chargé la classe, la nouvelle de la classe est ignoré.

Par exemple, j'ai utilisé les chargeurs de classe que de la charge des classes de LDAP ou SGBDR

Le déploiement à chaud devient une nécessité dans le monde Java lorsque le serveur d'applications est devenu "mainstream" pour Java EE ( et aussi créer le besoin pour les micro-conteneurs comme le printemps pour éviter ce genre de problème ) .

Le redémarrage de l'ensemble de l'application serveur après chaque compilation des lecteurs de quelqu'un de fou.

Donc, serveur d'application, fournisseur de cette "coutume" classe chargeurs à l'aide de déploiement à chaud, et à l'aide d'un fichier de configuration, que le comportement, DOIT être désactivé lors de l'ensemble de la production. Mais le compromis est que vous devez en utiliser des tonnes de mémoire dans le développement. Donc, la bonne façon de le faire est de redémarrer tous les 3 - 4 déploiements.

Ce n'est pas le cas avec les autres langues qui ont été conçus dès le départ pour charger leurs classes.

En Ruby par exemple, vous pouvez même ajouter des méthodes à une classe en cours d'exécution, remplacement d'une méthode à l'exécution, ou même d'ajouter une méthode unique à un unique objet spécifique.

L'inconvénient dans ce type d'environnement est bien sûr de la mémoire et de la vitesse.

J'espère que cette aide.

MODIFIER

J'ai découvert ce produit il y a quelques temps que les promesses que recharger, c'est de faire aussi simple que possible. Je ne me souviens pas le lien quand j'ai écrit cette réponse, et je le fais.

Il est JavaRebel de ZeroTurnaround

3voto

Vladimir Dyuzhev Points 10647

La JVM de Sun fixe l'espace PermGen de manière définitive, et finalement tout est consommé (oui, apparemment en raison d'un bogue dans le code lié au chargeur de classes) => MMO.

Si vous pouvez utiliser la machine virtuelle Java d'un autre fournisseur (par exemple celle de Weblogic), elle étend dynamiquement l'espace PermGen, de sorte que vous n'obtiendrez jamais de MOO lié à Permgen.

0voto

Ron Points 1149

Quelle version de Java utilisez-vous? Il y avait des bogues au début de Sun 1.4.2, mais cela fonctionne depuis très longtemps.
BTW, comment allez-vous annoncer la nouvelle à votre chef d'équipe? Êtes-vous le chef d'équipe?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X