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

Collection et Stream Java Discussion :

Problème de taille mémoire


Sujet :

Collection et Stream Java

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    511
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 511
    Points : 386
    Points
    386
    Par défaut Problème de taille mémoire
    Bonjour

    J'ai une servlet de sauvegarde de bdd qui génère et retourne un fichier texte sql zippé. la taille du fichier fait environ 25Mo de données (8.2 Mo zippé)
    Les données sont stokées dans une StringBuffer avant compression.
    La mémoire allouée au système est celle du package d'installation sans modif.
    Depuis peu, j'ai cette erreur qui remonte et je ne peux plus faire de sauvegarde:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    5 déc. 2013 10:01:10 org.apache.catalina.core.StandardWrapperValve invoke
    GRAVE: "Servlet.service()" pour la servlet gest_mat a généré une exception
    java.lang.OutOfMemoryError: Java heap space
    	at java.util.Arrays.copyOf(Arrays.java:2882)
    	at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:100)
    	at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:390)
    	at java.lang.StringBuffer.append(StringBuffer.java:224)
    	at administration.SauvegardeBdd.sauvegardeSql(SauvegardeBdd.java:67)
    	at administration.SauvegardeBdd.sauvegardeBdd(SauvegardeBdd.java:41)
    	at administration.IndexAdministration.main(IndexAdministration.java:115)
    	at index.GestMat.doGet(GestMat.java:395)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
    Config: Java 7 / Tomcat 7 / Mysql 5.5

    Pouvez vous m'aiguiller
    Merci

  2. #2
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 564
    Points : 21 629
    Points
    21 629
    Par défaut
    Citation Envoyé par Mengué georges Voir le message
    Les données sont stokées dans une StringBuffer avant compression.
    Ne pas faire ça me semble la piste la plus évidente.

    Stocker dans un fichier, ou envoyer dans la socket, ou quoi que ce soit d'autre que garder un fichier de plusieurs mégas en mémoire juste pour le compresser...

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    511
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 511
    Points : 386
    Points
    386
    Par défaut
    La solution ce serait quoi shématiquement ?

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    394
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 394
    Points : 639
    Points
    639
    Par défaut
    Bonjour,

    Utilise un BufferedOutputStream* :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    OutputStream bufferedOutputStream = new BufferedOutputStream(new GZIPOutputStream(new FileOutputStream("monFichier.tar.gz")));
    pour écrire tes données dans un fichier plutôt que de tout stocker en mémoire et écrire d'un coup l'ensemble.

    A chaque fois que tu appelles la méthode bufferedOutputStream.write() Java stock tes données en mémoire jusqu'à atteindre la taille limite du buffer. Quand la taille limite du buffer est atteinte, Java écrit ce qu'il a en mémoire dans le flux et vide le buffer. Et ainsi de suite...

    * Si tu veux écrire des String plutôt que des byte[] tu peux utiliser BufferedWriter à la place :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Writer bufferedOutputWriter = new BufferedWriter(new OutputStreamWriter(new GZIPOutputStream(new FileOutputStream("monFichier.tar.gz"))));
    bufferedOutputWriter.write("toto");
    bufferedOutputWriter.close();
    Romain.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    511
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 511
    Points : 386
    Points
    386
    Par défaut
    Donc si je suis ton rasonnement:
    je stoke à la volé mes données sql dans un fichier au fil du traitement puis je zip ce fichier que je renvoie

    Erreur, je rectifie:
    A chaque élément à sauvegarder (table), j'appelle la méthode bufferedOutputStream.
    Ce que j'ai du mal à appréhender c'est le cheminement (je suis un autodidacte à la retraite) qui pour vous qui êtes de la partie est une évidence.

  6. #6
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 564
    Points : 21 629
    Points
    21 629
    Par défaut
    En fait, il serait encore plus simple de zipper ce fichier à la volée et de renvoyer à la volée le résultat zippé.

    Et si ce que tu demandes, c'est comment faire ça, nous n'allons évidemment pas deviner qu'est-ce que tu appelles "renvoyer." C'est quoi ton protocole, c'est quoi tes interfaces.

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    511
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 511
    Points : 386
    Points
    386
    Par défaut
    Mon appli est web du type MCV2 qui est déployée localement via un pack qui comprend la jvm, tomcat et mysql, les réseaux et serveurs étant verrouillés par la direction informatique.
    J'ai installé un démonstrateur dans le Cloud d'AppFoghttp://sigmaint.eu01.aws.af.cm/gest_matlog jojo; pass bill

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    394
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 394
    Points : 639
    Points
    639
    Par défaut
    Avec le code que je t'ai donné tu écris directement un flux "gzippé" (grâce au new GZIPOutputStream()). Dans mon exemple j'ai écris dans un fichier (grâce au new FileOutputStream()) mais tu pourrais écrire dans un flux ouvert avec le client... A la place du FileOutputStream passe le stream que tu avais avant.

    Romain.

  9. #9
    Expert éminent sénior
    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 : 45
    Localisation : Belgique

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 804
    Points
    48 804
    Par défaut
    Et bien, je dirais qu'une solution serait un truc du genre

    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
    try (ZipOutputStream zos = new ZipOutputstream(response.getOutputStream())){
      zos.putNextEntry(new ZipEntry("datas.sql"));
      try(PrintWriter pw = new PrintWriter(new OutputStreamWriter(zos,"UTF-8"))) {
        generateSql(bw);
      }
    }
     
    ....
     
    private void generateSql(PrintWriter writer){
       //....
       writer.println("insertor into machin des trucs");
       writer.println("insertor into machin des autres trucs");
       //...
    }

  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    511
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 511
    Points : 386
    Points
    386
    Par défaut
    Bonjour à tous

    Je souhaiterai rester compatible à java 6

  11. #11
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,


    Citation Envoyé par Mengué georges Voir le message
    Je souhaiterai rester compatible à java 6
    Et donc ? Quel est le problème ?


    a++

  12. #12
    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
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Salut,
    Citation Envoyé par adiGuba Voir le message
    Et donc ? Quel est le problème ?
    Juste le try-with-resources utilisé dans l'exemple de @Tchize_.

    Citation Envoyé par Mengué georges Voir le message
    Je souhaiterai rester compatible à java 6
    Ce lien explique très bien la correspondance entre le try-with-resource et l'écriture "à l'ancienne", avec try/finally.

  13. #13
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    511
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 511
    Points : 386
    Points
    386
    Par défaut
    juste qu'eclipse génère une erreur et m'impose la compilation en java7

    ->Set project compiler compliance settings to 1.7

  14. #14
    Expert éminent sénior
    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 : 45
    Localisation : Belgique

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 804
    Points
    48 804
    Par défaut
    Version java 6, pas dure à adapter pourtant


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    ZipOutputStream zos = new ZipOutputstream(response.getOutputStream());
    try{
      zos.putNextEntry(new ZipEntry("datas.sql"));
      PrintWriter pw = new PrintWriter(new OutputStreamWriter(zos,"UTF-8"))
      try {
        generateSql(pw);
      } finally {
        pw.close();
      }
    } finally {
    zos.close();
    }

  15. #15
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    511
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 511
    Points : 386
    Points
    386
    Par défaut
    Bien merci pour l'exemple
    Après test il semble que l'espace mémoire utilisé soit inférieur. Il me faut aller chez les utilisateurs pour voir ce qu'il en est.

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

Discussions similaires

  1. Graphisme, imagerie problème de taille mémoire ?
    Par colorid dans le forum Langage
    Réponses: 8
    Dernier message: 23/02/2008, 08h37
  2. problème de taille et de mémoire
    Par soria_t dans le forum C
    Réponses: 31
    Dernier message: 22/02/2007, 08h58
  3. Réponses: 25
    Dernier message: 16/07/2003, 20h41
  4. [langage] Problème de taille de fichier à mettre dans
    Par And_the_problem_is dans le forum Langage
    Réponses: 10
    Dernier message: 13/08/2002, 09h41
  5. Problème avec la mémoire virtuelle
    Par Anonymous dans le forum CORBA
    Réponses: 13
    Dernier message: 16/04/2002, 16h10

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