samedi 9 février 2008

Optimisation de la mémoire de la JVM pour Eclipse

En voila un sujet qui fache !! La mémoire utilisée par Eclipse. Et c'est légitime que ce sujet déchaine les passions tant il est important de se pencher sur ce problème pour augmenter la productivité des utilisateurs eclipse.

En effet, avec une configuration par défaut, Eclipse est parfaitement adapté pour des projets simple de taille moyenne diront nous, cad sans dépendances complexes, sans avoir besoin de 1000 et 1 plugins et frameworks en tout genre.

Dès qu'il sagit de developper dans un environnement projet complexe (+ de 10 projets, + de 5 frameworks, RCP + WTP + Hibernate + Spring + Junit + BIRT + etc...) une configuration adaptée s'impose ! Car sinon on frole le drame ! Un environnement de développement instable et une machine qui "rame" comme jamais...
Symptomes: Des temps de chargement, de lancement, de build, de compilation ou de déploiement extrèmement longs et surtout une floppée de messages d'erreurs désagréables indiquant grossomodo qu'Eclipse manque de mémoire et vous incitant à redémarrer Eclipse (et la JVM par la même occasion).
Et quand on voit des popup "Eclipse need more memory... Do you want to exit the workbench now ? Yes. No." ou des OutOfMemoryException toutes les 2 heures d'utilisation, il y a de quoi s'arracher les cheveux !!!
Car redémarrer Eclipse implique premièrement d'arreter la tache en cours, d'attendre 2 minutes qu'il redémarre puis accessoirement de relancer le serveur d'application en cours (environ 2 minutes) et de redémarrer le client RCP puis de se remettre dans la configuration avant le re-démarrage "forcé"... Environ 5 minutes de perdu seulement diront certains... mais a raison de 4 fois par jour, ca représente 20 minutes minimum par développeur au sein d'un équipe ! Charge non négligeable AMHA !

Premièrement, il n'y a pas de secret, dans une configuration complexe il faudra un minimum de 1Go de RAM, 2Go de préférence voir 3 à 4Go pour les plus gourmands ! (Ceux qui font de la médélisation UML + des jeux en LAN + Eclipse...) Sans oublier une machine performante tant au niveau processeur (Intel Core 2 Duo / AMD Athlon 64) que pour le reste...

Deuxièment, le lanceur Eclipse (raccourci ou bat ou cmd) doit comporter des arguments spécifiques à la JVM pour paramètrer l'utilisation de la mémoire vive. Pour cela on peut ajouter le paramètre "-vmargs" suivi de propriétés à passer à la machine virtuelle java.

Pour info, dans "vmargs" on trouve "vm" soit "virtual machine" et "args" soit "arguments"... rien de bien compliqué.

Ensuite les propriétés que l'on peut passer à la machine virtuelle dépendent de votre configuration matérielle et de votre utilisation d'Eclipse... Voici des préconisations qui correspondent à un besoin particulier (le mien)... à vous d'adapter et de tester si cela vous convient au mieux ou pas.

On a pour habitude d'utiliser la propriété "-Xmx256m" pour augmenter la mémoire maximum utilisable par la JVM (Mx = Max et 256m = 256Mo de mémoire) mais il y est des cas ou cela ne suffit pas comme vu ci dessus.

Il est aussi possible de spécifier à la JVM la mémoire minimum allouée par la propriété "-Xmx256m" par exemple.

Et pour finir on peut imposer la taille du permGen Space* avec les propriétés "-XX:PermSize=64m" et "-XX:MaxPermSize=64m" par exemple, respectivement la taille par défaut allouée pour le permGen Space et sa taille maximum. (* terme défini et expliqué à la fin de cet article)

EDIT: Après étude, il faut ajouter "-XX:+CMSPermGenSweepingEnabled -XX:+CMSClassUnloadingEnabled" à la liste des paramètres afin d'autoriser le garbage collector à décharger des classes dynamiquement et de nettoyer les objets...

Toutes ces propriétés combinées permettant d'optimiser la gestion de la mémoire par la JVM en charge de faire fonctionner Eclipse ! Ce ne sont pas les seules existantes... mais les seules dont on parle dans cet article.

Voici quelques préconisation fonction de la mémoire RAM de votre machine.

Pour 512Mo de Ram: -vmargs -Xms256m -Xmx256m -XX:PermSize=64m -XX:MaxPermSize=64m -XX:+CMSPermGenSweepingEnabled -XX:+CMSClassUnloadingEnabled

Pour 1Go de Ram: -vmargs -Xms512m -Xmx512m -XX:PermSize=128m -XX:MaxPermSize=128m -XX:+CMSPermGenSweepingEnabled -XX:+CMSClassUnloadingEnabled

Pour 2Go de Ram: -vmargs -Xms768m -Xmx768m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:+CMSPermGenSweepingEnabled -XX:+CMSClassUnloadingEnabled

Après, n'ayant pas testé les configurations supérieures à 2Go, il vaut mieux ne pas se mouiller ! Chacun son opinion sur la question... on a tous des sensibilités différentes quand aux réactions de sa machine.

Qu'est ce que le heap space de la JVM:
Les propriétés -Xms768m et -Xmx768m permettent de spécifier la taille du heap space de la JVM, la taille de la mémoire utilisée pour faire vivre les objets java, la taille du dépot où sont stockés les objets en vie, les objets morts et la mémoire libre. C'est le Garbage Collector (GC) de la JVM qui s'occupe de nettoyer tout ca en fonction de la taille allouée à la mémoire. Un objet inutilisé (aucun pointeur (variable) qui y fait référence) est théoriquement supprimé de la mémoire par le GC quand celui ci se charge de nettoyer la mémoire.

Qu'est ce que le permGen space de la JVM:
Spécifique à la JVM Sun, cette zone mémoire contient tout ce qui n'est pas géré par le GC; tout ce qui est relatif au classes (leur structure: méthodes, champs, annotations...), les champs static, les chaines littérales... On spécifie le permGen space avec les propriétés -XX:PermSize=256m et -XX:MaxPermSize=256m par exemple. Plus on a de classes différentes plus il faut augmenter la taille de cette zone mémoire.

-XX:+CMSPermGenSweepingEnabled -XX:+CMSClassUnloadingEnabled ?


Ressources:
http://www.eclipsezone.com/eclipse/forums/t61618.html
http://edocs.bea.com/wls/docs61/perform/JVMTuning.html
http://www.developpez.net/forums/showthread.php?t=438282
http://java.sun.com
http://java.sun.com/javase/technologies/hotspot/gc/gc_tuning_6.html
http://java.sun.com/docs/hotspot/HotSpotFAQ.html
http://java.sun.com/performance/reference/whitepapers/6_performance.html
http://wiki.eclipse.org/FAQ_How_do_I_increase_the_permgen_size_available_to_Eclipse%3F
etc...

7 commentaires:

  1. Bonjour,
    juste un petit mot pour te remercier de cet article qui m'a permis de me tirer d'affaire d'un problème de dépassement de mémoire de ma JVM sous Eclipse ;)

    Ma machine ayant 3 go de RAM j'ai pu testé avec succès les arguments :
    Pour 2Go de Ram: -vmargs -Xms768m -Xmx768m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:+CMSPermGenSweepingEnabled -XX:+CMSClassUnloadingEnabled

    Tout fonctionne parfaitement maintenant !
    Un grand merci ;)

    Arnaud

    RépondreSupprimer
  2. Idem, merci beaucoup.
    Contrairement à beaucoup d'autres articles, tu explique la théorie, c'est bien plus agréable de savoir exactement ce qu'on fait.
    Petit ajout : il semblerait qu'on puisse, sous Windows, configurer ces paramètres dans le fichier "eclipse.ini".
    Pac

    RépondreSupprimer
  3. Je tiens à vous remercier vivement pour cet article qui m'a permis de bien maîtriser les agruments de la JVM passés à Eclipse pour lui assurer un bon fonctionnement.

    Merci encore une fois.

    RépondreSupprimer
  4. ***

    - Optimisation de la mémoire de la JVM pour Eclipse

    ***

    Par défaut, Eclipse est tout à fait adapter pour des projets « standard » de taille moyenne et qui ne demandent pas beaucoup de dépendances complexes.
    Par contre dès qu’il s’agit de développer dans un environnement plus complexe avec plusieurs Frameworks et plugins, cela peut facilement tourner au drame et avoir quelques erreurs dues à l’insuffisance de mémoire notamment dans la zone mémoire « permGen space », comme « Eclipse need more memory… Do you want to exit the workbench now ? » ou « OutOfMemoryException« . Ce genre d’erreur est assez répétitif et nous fait perdre beaucoup de temps.

    Alors pour remédier à tout cela, la solution est de passer des paramètres au lancement de Eclipse. Ces paramètres dépendent de la configuration de notre machine.

    ====>plus détails:
    http://learninformatique.blogspot.com

    RépondreSupprimer
  5. Merci pour cet article très clair qui explique bien les différents arguments disponibles pour gérer la mémoire dans Eclipse. C'est sûr que dès lors que nos projets deviennent importants, ces soucis de crash d'Eclipse faute de mémoire est à s'arracher les cheveux !

    RépondreSupprimer
  6. Ce commentaire a été supprimé par l'auteur.

    RépondreSupprimer
  7. Bonjour Cyril Lakech,

    Très bon article du début à la fin ! Tu relates correctement les technologies utilisées, les problèmes rencontrés et l'énervement du au temps passé à reboot toujours pour le même problème... Ton explication sur le rapprochement entre JVM et composants-machine est concise et efficace. Je viens de lancer avec la suite d'arguments qui correspondait à ma configuration, ça à l'air de bien tourner. A voir par la suite... Merci !

    RépondreSupprimer