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

Langage Java Discussion :

probleme de OutOfMemory


Sujet :

Langage Java

  1. #1
    Membre éclairé Avatar de L4BiN
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2006
    Messages
    432
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2006
    Messages : 432
    Par défaut probleme de OutOfMemory
    Bonjour,

    j'essai de corriger un probleme d'en appli qui fait un import de donnée assé conséquent.

    En gros apres 20 minute d'import de données on se prend dans la face un :
    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
    !ENTRY org.eclipse.core.jobs 4 2 2009-04-23 17:13:56.632
    !MESSAGE An internal error occurred during: "Importing Simulation Results".
    !STACK 0
    java.lang.OutOfMemoryError: GC overhead limit exceeded
    	at java.util.regex.Matcher.<init>(Matcher.java:207)
    	at java.util.regex.Pattern.matcher(Pattern.java:888)
    	at fr.ifp.first.externalapp.PropertyMatcher.find(PropertyMatcher.java:201)
    	at fr.ifp.first.externalapp.ui.io.ExternalDelegateParser.saveProductionResults(ExternalDelegateParser.java:630)
    	at fr.ifp.first.externalapp.ui.io.ExternalDelegateParser.saveProductionResults(ExternalDelegateParser.java:513)
    	at fr.ifp.first.externalapp.ui.io.ExternalDelegateParser.addDataToStorage(ExternalDelegateParser.java:201)
    	at fr.ifp.first.externalapp.outputparser.AbstractOutputFileParser.addDataToStorage(AbstractOutputFileParser.java:65)
    	at fr.ifp.first.externalapp.outputparser.XSILParser.parse(XSILParser.java:179)
    	at fr.ifp.first.externalapp.outputparser.AbstractDelegateParser.parse(AbstractDelegateParser.java:52)
    	at fr.ifp.first.externalapp.outputparser.DefaultDelegateParser.addSelectedResultsToStorage(DefaultDelegateParser.java:65)
    	at fr.ifp.first.externalapp.ui.io.ExternalImportJob.loadResults(ExternalImportJob.java:284)
    	at fr.ifp.first.externalapp.ui.io.ExternalImportJob.run(ExternalImportJob.java:143)
    	at org.eclipse.core.internal.jobs.Worker.run(Worker.java:55)
     
    !ENTRY org.eclipse.core.jobs 4 2 2009-04-23 17:46:15.286
    !MESSAGE An internal error occurred during: "Importing Simulation Results".
    !STACK 0
    java.lang.OutOfMemoryError: GC overhead limit exceeded
    Ce qui vous me l'accorderez est fort désagréable.
    Mais il s'avère que ce bug vient de ce code si:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     public int find(String key) {
            synchronized (patterns) {
                key = key.toLowerCase();
                for (Pattern pattern : patterns) {
                   Matcher matcher = pattern.matcher(key); 
                    if (matcher.find()) {
                        return properties.get(pattern);
                    }
                }
                return DefineProperty.UNKNOWN_TYPE.code();
            }
        }
    Est ce que quelqun sait ce qui est la cause d'un outofmemory sur les matcher ???

    Merci d'avance

  2. #2
    Membre éprouvé Avatar de jean.2edi
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    106
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juillet 2008
    Messages : 106
    Par défaut
    Pattern.matcher() est consommateur, si la mémoire devient insuffisante il est possible que ça plante à ce moment là...
    Tous les essais plantent au même endroit (dans Pattern.matcher()) ?
    Tu as essayé d'augmenter la mémoire pour voir s'il tient plus longtemps ?
    Quelle est la volumétrie : combien de lignes importées et combien de Pattern testés ? Est-ce que tu peux montrer un exemple de Pattern et de clé testés ?
    Dernière question : pourquoi synchroniser les patterns ? Il me semble que Pattern est thread-safe mais pas Matcher, si tu crées un Matcher à chaque fois, pas de problème dans ton code à part la mémoire... ou alors tu peux réutiliser le matcher avec reset().

  3. #3
    Membre éclairé Avatar de L4BiN
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2006
    Messages
    432
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2006
    Messages : 432
    Par défaut
    Merci pour tes réponses.
    1: tous les essais plante effectivement à cette ligne.
    2: avec une mémoire plus importante ca marche, mais les contraintes des clients à qui est fourni cette application m'oblige a trouver une solution Java au probleme.
    3: Je pense comme tu l'a indiqué que c'est peut etre de créer et recréer des Matcher qui cause le problème. Je vais essayer la solution du reset.
    (pour indication le patterns contient a chaque fois 1019 element, et la clé key est un string du genre "ppmmi").

    Merci

  4. #4
    Membre éprouvé Avatar de jean.2edi
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    106
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juillet 2008
    Messages : 106
    Par défaut
    clé key est un string du genre "ppmmi"
    Tu es certain d'avoir besoin de Pattern ?

    Il peut y avoir beaucoup d'optimisation possible dans les expressions rationnelles, les remplacer par des String.indexOf(), faire des tests (if(key.startsWith("p")) avant, les simplifier, les regrouper pour séparer tes 1019 cas après, etc...
    Si le reset ne marche pas, donne quelques exemples d'expressions et de clés.

  5. #5
    Membre Expert Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 690
    Par défaut
    clé key est un string du genre "ppmmi"
    Si tes expressions régulières ne contiennent aucun caractère spécial qui fait l'interet des expression régulière, autant ne pas les utiliser.

    La méthode contains() de la classe String est suffisante pour remplacer ton find() et sera moins consommatrice en mémoire et plus rapide.

  6. #6
    Membre éclairé Avatar de L4BiN
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2006
    Messages
    432
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2006
    Messages : 432
    Par défaut
    Bonjour,

    Oui je suis certain de devoir utilisé des Patterns car les clé sont pas toutes comme je l'avais décris au dessus.

    De plus pour revenir sur la ligne synchronized(patterns)... en fait patterns est une Arraylist à cette endrois.

    Je corrige des bugs de programme que je n'ai pas codé moi meme donc desolé si je suis un peu flou.

    Merci

  7. #7
    Membre éclairé Avatar de L4BiN
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2006
    Messages
    432
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2006
    Messages : 432
    Par défaut
    Bonjour,

    grace au logiciel YourKit j'ai plus localiser ou le programme consommais le plus.
    60 % de la consomation cpu se fait dans le parsing de fichier xml et là je ne peut rien y faire (a part changer le fonctionnement global en passant sur des fichier asciii ce qui serai surement mieux mais je ne peux pas).

    40 % de la conso vient de la methode si dessous. j'ai commenter les deux lignes qui consomme le plus.

    Je ne sais pas comment améliorer le code... si vous pensez a quelque chose je suis tout ouie.
    Merci d'avance

    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
     public void setPattern(int type, String regex) {
     
            synchronized (patterns) { // patterns est une Arraylist
                regex = regex.toLowerCase();
                ArrayList<Pattern> list = new ArrayList<Pattern>();
     
                // search all patterns that already match regex
                Matcher matcher;
                for (Pattern pattern : patterns) {
                    matcher = pattern.matcher(regex); // ici c'est 17 % du CPU
                    if (matcher.find()) { // c'est 10 % du cpu
                        list.add(pattern);
                    }
                }
                // remove all patterns that already match regex
                for (Pattern pattern : list) {
                    patterns.remove(pattern);
                    properties.remove(pattern);
                }
     
                // add (regex,type) in maps
                regex = "^" + regex.trim().toLowerCase() + "$";
                Pattern pattern = Pattern.compile(regex);
                patterns.add(pattern);
                properties.put(pattern, type);
            }
        }

  8. #8
    Membre Expert Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 690
    Par défaut
    Attention j'ai l'impression que tu confond consomation mémoire et CPU, je peux te faire un programme de 2 lignes qui va manger 100% de CPU et presque aucune mémoire et vice versa.

    Dans le cas de l'Out of memory c'est la consommation mémoire et non CPU qu'il faut surveiller.

  9. #9
    Membre éclairé Avatar de L4BiN
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2006
    Messages
    432
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2006
    Messages : 432
    Par défaut
    Effectivement,

    Mais j'ai tout de meme testé avec les 2 cpu et mémoire.
    Niveau cpu c'est comme indiqué dans le code,

    et niveau memoire la méthode prend les quasi 100% de la mémoire.

    Le probleme n'est pas que le code soit faut, car ca fonctionne sur des fichiers de petite taille. Mais comme je suis obligé d'utiliser les Pattern.matcher etc...
    alors les gros fichiers plante systematiquement, la seul solution que j'ai trouvé pour le moment est d'augmenter la mémoire de l'appli, mais ce n'est pas une solution acceptable pour les clients... donc je suis bloqué.... aih aih..

    Autre solution serai de passer sur un autre format que les fichier xml, mais la trop de travail et pas assez de temps.

    Merci

  10. #10
    Membre Expert Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 690
    Par défaut
    Je pense qu'une solution serait de stoker uniquement la String du pattern dans l'ArrayList plutôt qu'un objet pattern en entier.
    Ca devrait te permettre d'économiser en mémoire. Par contre il te faudra recompiler le pattern si tu as besoin de l'utiliser, donc potentiellement diminuer la performance.

  11. #11
    Membre éprouvé Avatar de jean.2edi
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    106
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juillet 2008
    Messages : 106
    Par défaut
    D'accord avec Uther. Il faut souvent choisir entre mémoire et temps ! Puisque la mémoire est une contrainte dans ton cas, il vaut mieux ne pas mettre les Pattern dans ta liste.

    Pour le parsing Xml : qu'est ce que tu utilises ? As tu besoin d'avoir tout en mémoire ou peux-tu utiliser une bibliothèque comme commons configuration ?
    Est-ce que tu peux parser ton Xml, mettre tout ce que tu as à chercher de côté avant de faire tes recherches.

  12. #12
    Membre éclairé Avatar de L4BiN
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2006
    Messages
    432
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2006
    Messages : 432
    Par défaut
    Merci pour vos réponses, je vais tester les différentes suggestions que vous me proposé.

    Je reviendrai vers vous le temps d'etudier le code afin de pouvoir répondre à toutes ces questions.

    merci

  13. #13
    Membre éclairé Avatar de L4BiN
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2006
    Messages
    432
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2006
    Messages : 432
    Par défaut
    Bonjour,

    finalement j'ai trouver que le probleme de memoire venai d'un autre endrois.

    J'aurais voulu savoir comment faire pour localiser les objets les plus couteux au niveau de la memoire.

    J'ai installer un profiler, mais je ne sais pas si je peux voir avec cette outils un objets specifique du code, la memoire qu'il prend, et localiser dans le sources l'objet?

    Merci

  14. #14
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,

    Citation Envoyé par L4BiN Voir le message
    J'aurais voulu savoir comment faire pour localiser les objets les plus couteux au niveau de la memoire.
    Tu peux utiliser VisualVM, qui est fournit avec le JDK6 depuis l'update 7 (outil jvisualvm) ou que tu peux télécharger ici : https://visualvm.dev.java.net/

    Il faut lancer le programme avec du Java 6 pour pouvoir le surveiller facilement.
    Tu en en particulier la possibilité de surveiller les instances en mémoire (voir screenshot), classé par taille mémoire utilisé...

    a++

  15. #15
    Membre éclairé Avatar de L4BiN
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2006
    Messages
    432
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2006
    Messages : 432
    Par défaut
    Bon j'ai identifier mon probleme.

    C'est que l'on utilise des ArrayList pour stocker un tres grand nomber de Double.

    Et que c ArrayList sont ensuite stocké dans des HashMaps.

    Question: Que faut il mieux que j'utilise à la place des ArrayList ??

    Est ce que un tableau de Double serait moins couteux ??

    Merci d'avance

  16. #16
    Modérateur
    Avatar de dinobogan
    Homme Profil pro
    ingénieur
    Inscrit en
    Juin 2007
    Messages
    4 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 4 073
    Par défaut
    Citation Envoyé par L4BiN Voir le message
    Est ce que un tableau de Double serait moins couteux ??
    Non, puisqu'un ArrayList est aussi un tableau de Double.
    Par contre, un tableau de double (le type de base double, pas l'objet Double) va te faire gagner en performances (pas de création/gestion d'objet) et en mémoire (c'est un type de base, pas un objet avec des données membres).
    A voir si tu peux l'intégrer dans ton projet, puisque tu ne manipuleras plus d'objets.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java
    Que la force de la puissance soit avec le courage de ta sagesse.

  17. #17
    Membre éclairé Avatar de L4BiN
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2006
    Messages
    432
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2006
    Messages : 432
    Par défaut
    Bon problème résolu. on a utilisé des fichiers ASCII pour stocker les donnée afin d'alléger les fichiers XML.

  18. #18
    Membre éclairé
    Inscrit en
    Juin 2006
    Messages
    570
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 570
    Par défaut
    Citation Envoyé par dinobogan Voir le message
    Non, puisqu'un ArrayList est aussi un tableau de Double.
    Par contre, un tableau de double (le type de base double, pas l'objet Double) va te faire gagner en performances (pas de création/gestion d'objet) et en mémoire (c'est un type de base, pas un objet avec des données membres).
    A voir si tu peux l'intégrer dans ton projet, puisque tu ne manipuleras plus d'objets.
    J'avais voulu un jour tester le gain de mémoire d'un tableau de int par rapport à un objet contenant plusieurs champs int (j'avais 3 ou 4 entiers seulement). Bah o surprise, le tableau prenait plus de place en mémoire. Alors je ne sais pas si cela serait vrai pour des objets plus conséquent par contre.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. probleme outOfMemory java
    Par flora806 dans le forum Langage
    Réponses: 6
    Dernier message: 28/02/2008, 16h40
  2. [OutOfMemory] probleme de delestage
    Par pierre.zelb dans le forum Général Java
    Réponses: 14
    Dernier message: 06/07/2005, 13h05
  3. Probleme sur les chaines de caractere
    Par scorpiwolf dans le forum C
    Réponses: 8
    Dernier message: 06/05/2002, 19h01
  4. [Kylix] Probleme d'execution de programmes...
    Par yopziggy dans le forum EDI
    Réponses: 19
    Dernier message: 03/05/2002, 14h50
  5. [Kylix] Probleme de nombre flottant!!
    Par yopziggy dans le forum EDI
    Réponses: 5
    Dernier message: 02/05/2002, 10h13

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