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 :

StringBuilder : problème de mémoire


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Mars 2005
    Messages
    546
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 546
    Par défaut StringBuilder : problème de mémoire
    Bonjour,

    Je vous explique mon souci. J'ai écrit une application qui récupère des données sur un serveur via REST. C'est données sont renvoyées en JSON et ensuite "décortiqués" pour créer mes objets dans mon appli.
    En une seule requête, je récupère jusqu'à 130 objets en format json.
    Pour lire les données j'utilise un StringBuilder, 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
                BufferedReader bufReader = new BufferedReader(new InputStreamReader(response));
                String sLine;
                StringBuilder sb = new StringBuilder();
     
                while ((sLine = bufReader.readLine()) != null) {
                    sb.append(sLine);
                    sb.append(lineSep);
                }
                try {
                    js = new JSONObject(sb.toString());
                } catch (JSONException ex) {
                    Logger.getLogger(HttpConnection.class.getName()).log(Level.SEVERE, null, ex);
                }
    Mon souci est que l'ensemble des données renvoyé représente environ 25Mo. sur mon PC ça marche bien, mais j'ai essayé sur une autre configuration et là Java me fait un "java heap space" sur le sb.append(), problème de mémoire apparemment.
    Du coup j'ai essayé de découper mes requêtes en plusieurs, à la première requêtes je renvoie la liste en ID de touts mes objets et ensuite, pour chaque ID je récupère les data.
    Le souci c'est que ça prend 10 minutes !!!!! (130 requêtes au lieu d'une seule !)
    Alors que de tout récupérer d'un seul coup ça me prend 40 secondes....
    Comment est-ce que je peux améliorer ça ?
    Merci de votre aide.

  2. #2
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Billets dans le blog
    2
    Par défaut
    Salut,

    Qu'entends-tu par "autre configuration". Autrement dit, quelle est la mémoire allouée au tas dans cette autre configuration (paramètre -Xmx dans la ligne de commande). Si découper le traitement en plusieurs sous-traitements peut consommer moins de mémoire, globalement ça en consommera autant : tu risques donc non seulement d'avoir une perte de performance due au découpage, mais également due au Garbage Collecting qui va forcément se déclencher pendant ton traitement. Si tu peux augmenter la taille du tas, autant le faire. Attention par ailleurs aux autres traitements de ton application, qui pourraient présenter des fuites de mémoire (que tu ne constaterais que sur cette autre configuration, pour diverses raisons : ça dépend de ce qui est fait dans l'application). Le traitement de ta requête peut également présenter des fuites (par exemple, je ne vois pas de close(), ni de try-with-resources pour ton BufferedReader...)
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  3. #3
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Mars 2005
    Messages
    546
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 546
    Par défaut
    Merci de ton retour.
    Mon PC est une station de dev sous linux avec java 7. L'autre configuration est un PC sous windows 7 avec la jre java 8. (d'ailleurs sur plusieurs autre config j'ai le même souci)
    en ce qui concerne les open et close des connexions et les try-catch, ils sont là, je ne les ai pas mis sur mon exemple pour ne pas alourdir...
    Après des recherches ils semblerait qu'on puisse augmenter la mémoire de la JVM mais dans mon cas, je ne veux pas y toucher car je me vois mal expliquer à mes clients qu'ils doivent lancer l'application avec une paramètre spécial...
    Je vais essayer de tester de tout lire en un seul coup sans faire de append, vu que c'est cela qui a l'air de poser problème...
    Merci !

  4. #4
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par jejeman Voir le message
    Après des recherches ils semblerait qu'on puisse augmenter la mémoire de la JVM mais dans mon cas, je ne veux pas y toucher car je me vois mal expliquer à mes clients qu'ils doivent lancer l'application avec une paramètre spécial...
    Bah, ce n'est pas un paramètre spécial : si ton application a besoin de X mémoire pour tourner, il faut lui allouer X mémoire. Maintenant, c'est sûr, il faut faire attention à ne pas gaspiller inutilement de la mémoire, et en particulier faire attention aux fuites. Ensuite, lorsque c'est possible, éviter de charger la mémoire et préférer des traitements de flux (en utilisant Jackson par exemple, ou GSon (com.google.gson.stream.JsonReader)).
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  5. #5
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 582
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 582
    Par défaut
    C'est vrai que 25Mo sous forme de JSON échangé entre deux ordinateurs, ça risque de prendre pas mal de place en mémoire une fois transformé en objets utilisables. De juste pas rentrer, en fait.

    Du coup la question à se poser est, combien de temps restent-ils en mémoire et quand en sortent-ils. Si par le plus grand des hasards ils ne sont pas censés y rester mais, à la place, rejoindre une base de données ou un fichier ou un site web ou que sais-je, dans ce cas il vaudrait mieux les traiter un par un. Ou dix par dix, ce genre de choses.
    Attention je ne dis pas de faire plusieurs REST. Je dis de traiter les données au fur et à mesure qu'on les lit dans la réponse.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  6. #6
    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
    Citation Envoyé par jejeman Voir le message
    Mon souci est que l'ensemble des données renvoyé représente environ 25Mo.
    En considérant que c'est de l'ASCII ou similaire, que les char java occupent 16 bits, que le StringBuilder a besoin de faire des ArrayCopy réguliers et augment sa taille par facteurs de 2, ce processus occupe un espace de travaille pouvant aller jusque 200M pour avoir au final un String à convertir en JSON.

Discussions similaires

  1. [WORD]Problème de mémoire
    Par Dnx dans le forum VBA Word
    Réponses: 17
    Dernier message: 05/10/2005, 14h48
  2. [Tomcat][Spring] Problème utilisation mémoire
    Par Wutintin dans le forum Hibernate
    Réponses: 12
    Dernier message: 08/09/2005, 14h57
  3. [Crystal Report]Problème de mémoire avec le moteur RDC
    Par sur_uix dans le forum SAP Crystal Reports
    Réponses: 3
    Dernier message: 26/05/2005, 09h09
  4. Problème de mémoire avec BDE
    Par Machuet dans le forum Bases de données
    Réponses: 3
    Dernier message: 13/07/2004, 10h11
  5. Problème de mémoire Affichage images
    Par Repti dans le forum C++Builder
    Réponses: 6
    Dernier message: 29/03/2004, 20h06

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