IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Tomcat et TomEE Java Discussion :

[Tomcat 5] Out Of Memory


Sujet :

Tomcat et TomEE Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Yaz
    Yaz est déconnecté
    Membre confirmé
    Inscrit en
    Avril 2002
    Messages
    56
    Détails du profil
    Informations forums :
    Inscription : Avril 2002
    Messages : 56
    Par défaut [Tomcat 5] Out Of Memory
    Bonjour,

    j'ai une appli java qui tourne sur le serveur Tomcat 5 et j'ai de temps à autre des OutOfMemory.

    Auriez-vous des idées pour résoudre ce problème ou pour identifier l'origine du problème ?

    Merci pour votre aide

  2. #2
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2005
    Messages
    55
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Février 2005
    Messages : 55
    Par défaut
    L'activité de déploiement et de repli (deploy/undeploy) conduit à terme à un java.lang.OutOfMemory : Permgen Space
    Il faut savoir qu'il n'y a pas grand chose à faire dans ce cas...

    Le bug est profond:
    Très grossièrement, si tu utilises dans ton application web des librairies externes qui font du chargement dynamique de classes (CGLIB, hibernate (fatal avec lazy=false), ....) et que tu la repli(undeploy), l'URLClassLoader de tomcat gardera les références sur les objets qui ont été chargés dynamiquement durant l'execution de l'appli ce qui empéche le ramasse-miette de les supprimer.

    il y a cependant des palliatifs:
    Le premier c'est d'utiliser un profiler et de délibérer manuellement les objets devant l'être.

    Le second, mais alors c'est vraiment du bricolage c'est d'augmenter la mémoire allouée au permgen de la JVM de Tomcat en ajoutant -XX:MaxPermSize=256M aux options de démarrage dans catalina.sh .Attention car cela crée des ralentissements, et ca ne fait que reporter le problème.

    Le troisième, si vous utilisez Tomcat en production, il est indispensable de repérer les applications qui bougent (beaucoup de cycles deploy/undeploy) et des les isoler dans une seconde instance de Tomcat dite "de test"... (c'est une politique genre debian) car il est possible de monter sur une même machine deux tomcat associées à deux JVM indépendantes, cela se fait en manipulant entre autre la variable CATALINA_BASE (et non pas CATALINA_HOME) si tu es sous Linux...

    En dehors de tout ceci, certaines librairies tel que la CGLIB comportent des fuites de mémoires reconnues, c'est pour ces raisons que des framework comme Spring ou Hibernate ont rendu l'utilisation de la CGLIB optionnel. (à noter qu'hibernate à eu du mal à rompre ses dépendances envers la CGLIB)

    Des outils comme jconsole sont assez utiles pour garder un oeil sur l'incrémentation du permgen jusqu'a ce qu'il atteigne sa valeur critique, et ça permet de mettre le doigt sur le problème (sans le résoudre)...

    Essaye de faire tourner ton appli avec d'autres conteneurs de servlets, pour voir si le problème persiste...

    bon courage...

  3. #3
    Yaz
    Yaz est déconnecté
    Membre confirmé
    Inscrit en
    Avril 2002
    Messages
    56
    Détails du profil
    Informations forums :
    Inscription : Avril 2002
    Messages : 56
    Par défaut
    Merci pour ta super réponse ! Bonne journée

  4. #4
    Membre éprouvé
    Homme Profil pro
    Développeur Java
    Inscrit en
    Janvier 2005
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Janvier 2005
    Messages : 63
    Par défaut
    Bonjour,

    Est ce que tu pourrais être plus précis concernant l'utilisation de CATALINA_HOME stp
    Citation Envoyé par TonioLeRital
    il est possible de monter sur une même machine deux tomcat associées à deux JVM indépendantes, cela se fait en manipulant entre autre la variable CATALINA_BASE (et non pas CATALINA_HOME) si tu es sous Linux...
    On m'a demandé dernièrement comment faire pour utiliser un Tomcat, avec deux applis ou chaque appli s'execute dans une JVM indépendante ?
    Est ce que c'est possible ? Ou est ce qu'il faut deux tomcat ?

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2005
    Messages
    55
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Février 2005
    Messages : 55
    Par défaut
    Bonjour,

    Citation Envoyé par a_defanti
    On m'a demandé dernièrement comment faire pour utiliser un Tomcat, avec deux applis ou chaque appli s'execute dans une JVM indépendante ?
    Est ce que c'est possible ? Ou est ce qu'il faut deux tomcat ?
    Avant toutes choses, sous quel OS es-tu car je l'ai déja fait sous Linux (debian et fedora), mais jamais sous windows.

  6. #6
    Membre éprouvé
    Homme Profil pro
    Développeur Java
    Inscrit en
    Janvier 2005
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Janvier 2005
    Messages : 63
    Par défaut
    Oui l'OS est Linux.

    Par contre suite à la demande qui m'a été faite, je ne sais pas quelle est la différence entre :
    _utiliser un Tomcat, avec deux applis ou chaque appli s'execute dans une JVM indépendante
    _utiliser deux tomcat avec chacun une appli

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2005
    Messages
    55
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Février 2005
    Messages : 55
    Par défaut
    Salut,
    Citation Envoyé par a_defanti
    _utiliser un Tomcat, avec deux applis ou chaque appli s'execute dans une JVM indépendante
    _utiliser deux tomcat avec chacun une appli
    Tomcat étant un conteneur d'applications dont la gestion des applications est géree par le mécanisme de chargement dynamique de classes (c'est le principe des plugins qui apportent des fonctionnalités supplémentaires à une application sans la redemarrer), on perdrait donc l'intérêt d'utiliser ce genre de conteneurs si les applications hebergées lancaient des processus (JVM) indépendants.
    Donc configurer 2 instances de tomcat ne revient pas à installer deux tomcats complets dans deux repertoires différents, mais à lancer deux JVM de tomcat qui coexistent sur le même serveur mais dont les ports d'attaque sont différents...(C'est comme quand tu ouvres deux IDE eclipse : bien qu'il n'y ait qu'un seul eclipse d'installé sur ta machine tu constates qu'avec ps -ax | grep eclipse ) il existe dans ta liste des processus 2 processus java (2 JVM) .)
    Cette approche me semble donc conceptuellement erronée...

    Voici un descriptif que j'ai rédigé pour installer deux instances de tomcat: j'y inclu aussi les modifications du mod_jk, l'installation d'un manager, etc... des infos que tu pourras sauter(surtout pour le mod_jk si tu n'as pas d'apache pluggé à tomcat)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
     
    ###########################################################################
    #### Installation de plusieurs instance de tomcat sur une seule machine.###
    ###########################################################################
     
    #-----------------------------------------------------
    #Soit $CATALINA_HOME le répertoire de base de tomcat.
    #------------------------------------------------------
     
    #S'assurer que $CATALINE_HOME et que $JAVA_HOME existe
     
    mkdir $CATALINA_HOME/otherInstances
    mkdir $CATALINA_HOME/otherInstances/tomcat2
    mkdir $CATALINA_HOME/otherInstances/tomcat2/webapps
    mkdir $CATALINA_HOME/otherInstances/tomcat2/logs
    mkdir $CATALINA_HOME/otherInstances/tomcat2/temp
    mkdir $CATALINA_HOME/otherInstances/tomcat2/server
    mkdir $CATALINA_HOME/otherInstances/tomcat2/server/webapps
    mkdir $CATALINA_HOME/otherInstances/tomcat2/work
     
    #Copier le contenu du repertoire conf de $CATALINA_HOME dans le répertoire ..../tomcat2/conf
     
    cd $CATALINA_HOME
    cp -R conf otherInstances/tomcat2/
    cp -R webapps/ROOT/ otherInstances/tomcat2/webapps/
     
    #Editer le fichier .../tomcat2/conf/server.xml : 
    1) Incrémenter de 100 la valeur du port d'arrêt du server (généralement on passe de 8005 à 8105)
    2) Commentez le connecteur HTTP : <Connector port="8080"....>
    3) Augmenter de 100 le port du connecteur AJP1.3. (généralement on passe de 8009 à 8109)
    4) Dans le host de votre choix (localhost par défaut) mettre à jour appBase="...../tomcat2/webapps/"
     
     
    #Editer le fichier workers.properties (dans $CATALINA_HOME/conf/jk) et rajouter :
    worker.list=tomcat2
    worker.tomcat2.port=8109
    worker.tomcat2.host=localhost
    worker.tomcat2.type=ajp13
     
     
    ##################################################
    ###Installation d'un manager pour cette instance #
    #################################################
     
    Editer le fichier mod_jk.conf (présent dans le sous-repertoire conf ou conf/jk de $CATALINA_HOME) et rajouter:
    Jkmount /manager2/* tomcat2
     
    #Copier le répertoire $CATALINA_HOME/server/webapps/manager dans ......./tomcat2/server/webapps/manager (le nom du rep. manager doit être remplacer par manager2)
    cp -R $CATALINA_HOME/server/webapps/manager $CATALINA_HOME/otherInstances/tomcat2/server/webapps/manager
     
    #Copier le fichier manager.xml de $CATALINA_HOME/conf/Catalina/localhost dans ...../tomcat2/conf/Catalina/localhost/manager2.xml
    cp $CATALINA_HOME/conf/Catalina/localhost/manager.xml $CATALINA_HOME/otherInstances/tomcat2/conf/Catalina/localhost/manager2.xml
     
    #Editer le fichier nouvellement copié et mettre à jour docBase="../server/webapps/manager2""
    (Le manager de la nouvelle instance de Tomcat sera accessible depuis l'url http://monNomDeDomaine/manager2/html)
     
    ############################################
    ### Script de démarrage de l'instance #####
    ############################################
     
    #Créer un script de démarrage et d'arrêt de la deuxième instance de tomcat (tomcat2).
     
    #!/bin/bash
    #SCRIPT A PARFAIRE!!!
    export JAVA_HOME="/usr/local/j2sdk"
    export CATALINA_HOME="/usr/local/tomcat"
    export CATALINA_BASE="$CATALINA_HOME/otherInstances/tomcat2"
     
    case "$1" in
    start)
            if [ -f $CATALINA_HOME/bin/startup.sh ];
                    then
                    echo $"Starting Tomcat2..."
                    su -l wwwadm -c "(export JAVA_HOME=/usr/local/j2sdk; export CATALINA_HOME=/usr/local/tomcat; export CATALINA_BASE=/usr/local/tomcat/otherInstances/tomcat2; /usr/local/tomcat/bin/startup.sh)"
             fi
             ;;
     
    stop)
            if [ -f $CATALINA_HOME/bin/shutdown.sh ];
                    then
                    echo $"Stopping Tomcat2..."
                    su -l wwwadm -c "(export JAVA_HOME=/usr/local/j2sdk; export CATALINA_HOME=/usr/local/tomcat; export CATALINA_BASE=/usr/local/tomcat/otherInstances/tomcat2; /usr/local/tomcat/bin/shutdown.sh)"
             fi
             ;;
     
    *)
             echo $"Usage: $0 {start|stop}"
            echo Usage : $0 "{start | stop}"
            ;;
    esac
     
     
    - Faire un apache graceful (pour le rafraichissement du mod_jk.conf).
    - Faire un tomcat2 start. (je propose de mettre le script tomcat2 dans /etc/init.d et l'inclure au systeme V via chkconfig).

  8. #8
    Membre extrêmement actif Avatar de Mister Nono
    Homme Profil pro
    Ingénieur Mathématiques et Informatique
    Inscrit en
    Septembre 2002
    Messages
    2 242
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur Mathématiques et Informatique
    Secteur : Santé

    Informations forums :
    Inscription : Septembre 2002
    Messages : 2 242
    Par défaut
    Citation Envoyé par TonioLeRital
    certaines librairies tel que la CGLIB comportent des fuites de mémoires reconnues, c'est pour ces raisons que des framework comme Spring ou Hibernate ont rendu l'utilisation de la CGLIB optionnel. (à noter qu'hibernate à eu du mal à rompre ses dépendances envers la CGLIB)
    Comment indiquer à Hibernate de ne pas utiliser la CGLIB afin de ne plus avoir de fuite mémoire ?

    Merci d'avance.

  9. #9
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2005
    Messages
    55
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Février 2005
    Messages : 55
    Par défaut
    Citation Envoyé par Mister Nono
    Comment indiquer à Hibernate de ne pas utiliser la CGLIB afin de ne plus avoir de fuite mémoire ?

    Merci d'avance.
    il y a tout d'abord le paramètre suivant :

    hibernate.cglib.use_reflection_optimizer=false
    ce qui force hibernate à utiliser le mécanisme de proxy du JDK (api reflectivité) plutot que celui de la CGlib.

    Mais de ce que j'avais pratiqué cela ne suffisait pas car dans les version 2 et 3.0 il y a de la dépendance "en dur" vers la CGLIB néanmoins les versions futures devait pouvoir s'en affranchir... je n'ais pas vérifié depuis... mais ça sent mauvais!!!

    As-tu essayé de changer de JVM pour voir si cela résoud tes problèmes...
    j'ai lu assez souvent que la JVM de BEA est plus optimisée pour un usage de type serveur, mais personnellement celle d'IBM arrive largement en premier sur mes tests de montée en charge.

    voilà,
    tiens moi au courant.
    a+

  10. #10
    Membre extrêmement actif Avatar de Mister Nono
    Homme Profil pro
    Ingénieur Mathématiques et Informatique
    Inscrit en
    Septembre 2002
    Messages
    2 242
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur Mathématiques et Informatique
    Secteur : Santé

    Informations forums :
    Inscription : Septembre 2002
    Messages : 2 242
    Par défaut
    Merci pour la réponse.

    J'ai donc ajouté ce tag dans le fichier de configuration de Hibernate :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    <property name="hibernate.cglib.use_reflection_optimizer">false</property>
    Ce qui m'étonne, c'est que j'utilise Hibernate 3 et que ce problème n'est pas été réglé par rapport à la version 2.

    Pourquoi ?

    Merci.

  11. #11
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2005
    Messages
    55
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Février 2005
    Messages : 55
    Par défaut
    Citation Envoyé par Mister Nono
    Merci pour la réponse.

    J'ai donc ajouté ce tag dans le fichier de configuration de Hibernate :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    <property name="hibernate.cglib.use_reflection_optimizer">false</property>
    Ce qui m'étonne, c'est que j'utilise Hibernate 3 et que ce problème n'est pas été réglé par rapport à la version 2.

    Pourquoi ?

    Merci.
    En effet, je ne disais pas que "ça sent mauvais" à la légère, car il me semblait avoir lu qu'ils n'ont pas réussi à rompre leur dépendance avec la CGlib alors qu'ils s'y étaient engagés, par contre...

    As-tu essayé de réinjecter dans tes .jar la dernière version de la CGlib (2.2 version beta), peut-être ont-ils "colmaté leur fuite"... mais attention garde toujours l'ancienne version sous la main même si cela semble fonctionner...

    Comment sais-tu qu'il y a une fuite mémoire? tu utilises quel outils le cas échéant?

Discussions similaires

  1. [XStream][String]out of memory
    Par Invité dans le forum Persistance des données
    Réponses: 8
    Dernier message: 10/01/2006, 14h52
  2. [C++] [gcc] out of memory
    Par fxp17 dans le forum GCC
    Réponses: 5
    Dernier message: 06/01/2006, 10h29
  3. [pb mémoire] out of memory d'eclipse
    Par Casp dans le forum Eclipse Java
    Réponses: 2
    Dernier message: 12/05/2005, 16h39
  4. Out of memory
    Par shurato dans le forum ANT
    Réponses: 1
    Dernier message: 10/11/2004, 16h19
  5. [JBuilder 8] Out of memory problem ...
    Par keros dans le forum JBuilder
    Réponses: 2
    Dernier message: 08/09/2003, 19h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo