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 :

java.lang.OutOfMemoryError: Java heap space


Sujet :

Langage Java

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    199
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 199
    Par défaut java.lang.OutOfMemoryError: Java heap space
    Bonjour,
    J'essaie de traiter un fichier de 628000 lignes environ. Voici mon code :

    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
    List polygonDataList = new LinkedList();
     
    BufferedReader dis = new BufferedReader(new InputStreamReader(mapForm.getPolygonFile().getInputStream()));                    
     
    String line = null;
    StringTokenizer st;
    // Datacontent est un nouveau type contenant, entre autres, un Double 'X', un Double 'Y' et une String 'geoid'
    Datacontent currentdata;
     
    while((line=dis.readLine()) != null){                        
         if (line.length() > 0){
             st = new StringTokenizer(line,"\t");
             currentdata = new Datacontent();                            
     
             while (st.hasMoreTokens()){                                
                   currentdata.setGeoid(st.nextToken());
                   currentdata.setX(Double.valueOf(st.nextToken()));
                   currentdata.setY(Double.valueOf(st.nextToken()));
             }
             polygonDataList.add(currentdata);
         }
    }
    Ce code me retourne systématiquement l'erreur citée en objet en me renvoyant à la ligne suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    currentdata = new Datacontent();
    Si je mets une trace, je m'aperçois que le nombre de lignes traitées ne dépasse jamais 131500 !

    Quel est le problème ? Si quelqu'un a une idée...

    Merci par avance.

  2. #2
    in
    in est déconnecté
    Membre Expert Avatar de in
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    1 612
    Détails du profil
    Informations personnelles :
    Localisation : France, Finistère (Bretagne)

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 612
    Par défaut
    si tu veux vraiment charger tous ces objets en mémoire, à part jouer sur la quantité de mémoire disponible pour ton appli, il n'y a pas 36 solutions.

    Es tu sûr de devoir tout charger ? Il n'est pas possible de procéder par "morceaux" ?

    Tu peux aller voir cette entrée de la FAQ : Comment connaitre la mémoire utilisée par notre application pendant son exécution ? et essayer de jouer avec les paramètres de ta JVM ...

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    199
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 199
    Par défaut
    Merci pour ta réponse.
    Je vais essayer de voir comment est allouée la mémoire grâce au lien que tu m'as indiqué...
    Sinon, qu'entends-tu par "procéder par morceaux" ? Comment est-il possible de ne charger qu'une partie d'un fichier ?
    Merci encore pour ton aide.

  4. #4
    in
    in est déconnecté
    Membre Expert Avatar de in
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    1 612
    Détails du profil
    Informations personnelles :
    Localisation : France, Finistère (Bretagne)

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 612
    Par défaut
    Je suggérais juste que pour ton traitement tu n'as peut être pas besoin de tout charger en mémoire. Mais ça dépend bien sûr de ce que tu souhaites faire.

    Le problème de mémoire ne vient pas forcément de la lecture du fichier mais de la place que prennent tous les objets de la liste ...

  5. #5
    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 jgfa9 Voir le message
    Sinon, qu'entends-tu par "procéder par morceaux" ?
    Cela dépend des traitements que tu vas faire sur ces données. C'est donc à toi que l'on doit poser les questions : pourquoi as-tu besoins de tout charger en mémoire ? Que vas-tu faire de ces données ?

    Sinon il serait bien de connaître la taille des données ? Par exemple quel est la longueur moyenne de geoid ? Je rappelle que sous les système Windows la mémoire est limité à 64Mo par défaut...



    Sinon, y-a-t-il une raison particulière d'utiliser une LinkedList ? Une ArrayList serait sûrement moins gourmande en limitant le nombre de référence.

    Enfin deux petites remarques : je ne vois pas le try/finally pour la libération du flux, et la déclaration des variables en début de méthode n'est pas très joli

    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
    List polygonDataList = new ArrayList();
     
    BufferedReader dis = new BufferedReader(new InputStreamReader(mapForm.getPolygonFile().getInputStream()));                    
    try {
    	String line = null;
    	while((line=dis.readLine()) != null){                        
    	     if (line.length() > 0){
    		 StringTokenizer st = new StringTokenizer(line,"\t");
    		 Datacontent currentdata = new Datacontent();                            
     
    		 while (st.hasMoreTokens()){                                
    		       currentdata.setGeoid(st.nextToken());
    		       currentdata.setX(Double.valueOf(st.nextToken()));
    		       currentdata.setY(Double.valueOf(st.nextToken()));
    		 }
    		 polygonDataList.add(currentdata);
    	     }
    	}
    	polygonDataList.trimToSize();
    } finally {
    	dis.close();
    }
    a++

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    199
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 199
    Par défaut
    Effectivement j'ai besoin de charger tous les éléments du fichier parce qu'ensuite je dois faire des sommes et des recherches sur ces éléments (par exemple vérifier que des éléments contenus dans d'autres listes ont un geoid qui apparait dans la liste 'polygonDataList')...
    Le champ 'geoid' comporte en moyenne 8 caractères.
    Merci pour les indications et les conseils que tu m'as donnés, je vais corriger mon code.
    Si tu en as d'autre au vu de mes réponses, encore merci !

  7. #7
    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
    Encore une chose, remplace ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    currentdata.setGeoid(st.nextToken());
    par cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    currentdata.setGeoid(new String(st.nextToken()));
    En effet, une chaine découpé pointe en fait sur les mêmes données que la chaine originale, mais avec un offset et une longueur différente. Ce qui fait qu'il y a toujours une référence sur les données initiale (la ligne complète dans ton cas).

    En utilisant le constructeur new String() tu crée une nouvelle chaine indépendante...


    a++

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    199
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 199
    Par défaut
    J'ai apporté les modifications suggérées à mon code mais j'ai toujours le même problème (mais après traitement de 170000 lignes et non plus 131000).
    Voici les traces obtenues en utilisation l'objet MemoryMXBean :
    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
    15 août 2008 16:13:43 (MapAction.java:4707) - 0 lignes traitées
    15 août 2008 16:13:43 (MapAction.java:4708) - init = 0(0K) used = 55079856(53788K) committed = 58400768(57032K) max = 66650112(65088K)
    15 août 2008 16:13:43 (MapAction.java:4707) - 10000 lignes traitées
    15 août 2008 16:13:43 (MapAction.java:4708) - init = 0(0K) used = 58171672(56808K) committed = 58400768(57032K) max = 66650112(65088K)
    15 août 2008 16:13:44 (MapAction.java:4707) - 20000 lignes traitées
    15 août 2008 16:13:44 (MapAction.java:4708) - init = 0(0K) used = 40838064(39880K) committed = 66650112(65088K) max = 66650112(65088K)
    15 août 2008 16:13:44 (MapAction.java:4707) - 30000 lignes traitées
    15 août 2008 16:13:44 (MapAction.java:4708) - init = 0(0K) used = 43502784(42483K) committed = 66650112(65088K) max = 66650112(65088K)
    15 août 2008 16:13:44 (MapAction.java:4707) - 40000 lignes traitées
    15 août 2008 16:13:44 (MapAction.java:4708) - init = 0(0K) used = 46317488(45231K) committed = 66650112(65088K) max = 66650112(65088K)
    15 août 2008 16:13:44 (MapAction.java:4707) - 50000 lignes traitées
    15 août 2008 16:13:44 (MapAction.java:4708) - init = 0(0K) used = 46071048(44991K) committed = 66650112(65088K) max = 66650112(65088K)
    15 août 2008 16:13:44 (MapAction.java:4707) - 60000 lignes traitées
    15 août 2008 16:13:44 (MapAction.java:4708) - init = 0(0K) used = 48883328(47737K) committed = 66650112(65088K) max = 66650112(65088K)
    15 août 2008 16:13:44 (MapAction.java:4707) - 70000 lignes traitées
    15 août 2008 16:13:44 (MapAction.java:4708) - init = 0(0K) used = 51601840(50392K) committed = 66650112(65088K) max = 66650112(65088K)
    15 août 2008 16:13:44 (MapAction.java:4707) - 80000 lignes traitées
    15 août 2008 16:13:44 (MapAction.java:4708) - init = 0(0K) used = 51359040(50155K) committed = 66650112(65088K) max = 66650112(65088K)
    15 août 2008 16:13:44 (MapAction.java:4707) - 90000 lignes traitées
    15 août 2008 16:13:44 (MapAction.java:4708) - init = 0(0K) used = 54387864(53113K) committed = 66650112(65088K) max = 66650112(65088K)
    15 août 2008 16:13:44 (MapAction.java:4707) - 100000 lignes traitées
    15 août 2008 16:13:44 (MapAction.java:4708) - init = 0(0K) used = 57203864(55863K) committed = 66650112(65088K) max = 66650112(65088K)
    15 août 2008 16:13:44 (MapAction.java:4707) - 110000 lignes traitées
    15 août 2008 16:13:44 (MapAction.java:4708) - init = 0(0K) used = 59746464(58346K) committed = 66650112(65088K) max = 66650112(65088K)
    15 août 2008 16:13:44 (MapAction.java:4707) - 120000 lignes traitées
    15 août 2008 16:13:44 (MapAction.java:4708) - init = 0(0K) used = 59438904(58045K) committed = 66650112(65088K) max = 66650112(65088K)
    15 août 2008 16:13:44 (MapAction.java:4707) - 130000 lignes traitées
    15 août 2008 16:13:44 (MapAction.java:4708) - init = 0(0K) used = 61937216(60485K) committed = 66650112(65088K) max = 66650112(65088K)
    15 août 2008 16:13:44 (MapAction.java:4707) - 140000 lignes traitées
    15 août 2008 16:13:44 (MapAction.java:4708) - init = 0(0K) used = 65754800(64213K) committed = 66650112(65088K) max = 66650112(65088K)
    15 août 2008 16:13:45 (MapAction.java:4707) - 150000 lignes traitées
    15 août 2008 16:13:45 (MapAction.java:4708) - init = 0(0K) used = 62571432(61104K) committed = 66650112(65088K) max = 66650112(65088K)
    15 août 2008 16:13:45 (MapAction.java:4707) - 160000 lignes traitées
    15 août 2008 16:13:45 (MapAction.java:4708) - init = 0(0K) used = 65071640(63546K) committed = 66650112(65088K) max = 66650112(65088K)
    15 août 2008 16:13:46 (MapAction.java:4707) - 170000 lignes traitées
    15 août 2008 16:13:46 (MapAction.java:4708) - init = 0(0K) used = 66532568(64973K) committed = 66650112(65088K) max = 66650112(65088K)
    Je ne comprends pas pourquoi il s'arrête à 64 Mo environ alors que les options d'allocation de mémoire sont les suivantes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    -J-Xms256m -J-Xmx512m -J-XX:PermSize=512m -J-XX:MaxPermSize=512m
    PS : cette fois, l'erreur lancée est la suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    java.lang.OutOfMemoryError: Java heap space
    java.lang.Double.valueOf(Double.java:475)
    sur la ligne de code suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    currentdata.setX(Double.valueOf(st.nextToken()));
    Y-a-t'il un problème sur cette ligne ?
    Merci encore pour votre aide.

  9. #9
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    ne touche pas au permsize, tu ne devrais pas en avoir besoin. Et c'est quoi c'est -J-.... ? A quoi est censé servir ce -J qui précède chaque option? Pourrais-tu afficher la ligne complète que tu tappe pour exécuter ton application?

  10. #10
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    199
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 199
    Par défaut
    Je développe sous NetBeans et voici la ligne en question du fichier etc/netbeans.conf :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    netbeans_default_options="-J-Dorg.netbeans.modules.tomcat.autoregister.token=1209477593265 -J-Dorg.netbeans.modules.tomcat.autoregister.catalinaHome=\"C:\Program Files\Apache Software Foundation\Apache Tomcat 6.0.16\" -J-client -J-Xss2m -J-Xms256m -J-Xmx512m -J-XX:PermSize=512m -J-XX:MaxPermSize=512m -J-Xverify:none -J-Dapple.laf.useScreenMenuBar=true -J-Dsun.java2d.noddraw=true"
    Merci pour votre aide à tous.

  11. #11
    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
    Citation Envoyé par tchize_ Voir le message
    Et c'est quoi c'est -J-.... ? A quoi est censé servir ce -J qui précède chaque option? Pourrais-tu afficher la ligne complète que tu tappe pour exécuter ton application?
    Le -J- permet normalement de passer des options à la JVM lorsqu'on utilise des outils du JDK (par exemple javac, javap, javadoc, etc...).

    Citation Envoyé par jgfa9 Voir le message
    Je développe sous NetBeans et voici la ligne en question du fichier etc/netbeans.conf :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    netbeans_default_options="-J-Dorg.netbeans.modules.tomcat.autoregister.token=1209477593265 -J-Dorg.netbeans.modules.tomcat.autoregister.catalinaHome=\"C:\Program Files\Apache Software Foundation\Apache Tomcat 6.0.16\" -J-client -J-Xss2m -J-Xms256m -J-Xmx512m -J-XX:PermSize=512m -J-XX:MaxPermSize=512m -J-Xverify:none -J-Dapple.laf.useScreenMenuBar=true -J-Dsun.java2d.noddraw=true"
    Ca c'est les options de Netbeans...

    C'est les options de lancement de ton application qu'il faut modifier.
    Si tu fais cela depuis Netbeans tu dois avoir la possibilité de changer cela quelque part...


    a++

Discussions similaires

  1. java.lang.OutOfMemoryError: Java heap space
    Par othmanbenhalima dans le forum Général Java
    Réponses: 12
    Dernier message: 08/01/2008, 17h46
  2. java.lang.OutOfMemoryError: Java heap space
    Par EvilAngel dans le forum Langage
    Réponses: 3
    Dernier message: 26/04/2007, 10h17
  3. [Findbugs] [Maven] java.lang.OutOfMemoryError: Java heap space
    Par albaille dans le forum Qualimétrie
    Réponses: 1
    Dernier message: 10/04/2007, 15h17
  4. Réponses: 4
    Dernier message: 18/09/2006, 10h02
  5. Eclipse erreur : java.lang.OutOfMemoryError: Java heap space
    Par sderecourt dans le forum Eclipse Java
    Réponses: 1
    Dernier message: 14/04/2006, 11h28

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