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

Java Discussion :

Un processus qui ralenti lors de son second appel


Sujet :

Java

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    116
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 116
    Points : 53
    Points
    53
    Par défaut Un processus qui ralenti lors de son second appel
    Bonjour à tous,
    Je suis en train de faire une application qui traite des listes de discussion.
    J'ai donc un objet Projet, qui contient un tableau d'objets Liste.
    Chaque objet Liste contient un tableau d'objets Message.
    Chaque objet Message est constitué de 12 champs : nom, date, mail ... etc.
    Tous ces objets sont sérialisés lors de chaque mise à jour de l'objet Projet ou Liste (Observer/Observable).

    Je lance mes processus à l'aide de SwingWorkers:
    - Lorsque j'ajoute une première liste et que j’extrais pour la première fois mettons 50000 messages, tout se déroule parfaitement, en un peu moins de 10 secondes.
    - Mais lorsque je réitère le processus pour la seconde fois en ajoutant une nouvelle liste avec 50000 Messages, un ralentissement énorme se fait vers 90%.
    - Et lorsque le processus parvient enfin à se terminer, je ne peux même pas dépasser les 2% pour l'ajout d'une troisième liste.

    J'ai téléchargé Memory Analyser, mais je ne vois pas grand chose dans les fuites potentielles, à part bien sûr des ArrayList énormes (mes 50000 messages), des objets String sur-utilisés (normal je fonctionne beaucoup avec des String) ou équivalents (normal aussi, par exemple pour les titres de messages), et un Thread énorme, le dernier à avoir été lancé (ça je pense aussi que c'est normal vu qu'il est bloqué !)

    Je me demande donc si :
    - un objet qui contient 2 tableaux de 50000 objets de 10 champs, soit donc un million de champs, c'est trop pour JAVA ?
    - j'ai abandonné les bases de données (H2) pour faire du tout objet et de la sérialisation car je pensais ça plus souple : faut-il que je fasse marche arrière (ça m'embêterai parce que j'avais eu des soucis de Heap Space avec les bdd) ?
    - y-a-t-il d'autres outils (dans Eclipse notamment) qui pourraient me dire ce qui ne va pas ?
    - lorsque je lance plusieurs SwingWorkers à la suite, ils devraient être exécutés les uns à la suite des autres non ? car j'en utilise lors de la sauvegarde (sérialisation) de mes objets, et en fait plusieurs se lancent en même temps (j'ai testé avec des fenêtres de jprogressbar indeterminate et il y en a 2 qui apparaissent en même temps) après le lancement du second processus puis se bloquent (lorsque je lance le 1er, tout va très vite et je n'en voit qu'une !).
    - Et de fait, la sérialisation se passe mal car je ne peux pas désérialiser ensuite.
    - Plus généralement sur les SwingWorkers : en fait je les ai utilisé car j'avais des soucis de mise à jour de ma progressbar d'extraction des messages. Ça marche très bien, mais fondamentalement je n'en ai pas vraiment besoin car je travaille séquentiellement (les traitements que je fais après sur les messages ne peuvent se faire que si les messages ont été extraits !). Dons je me retrouve à lancer plein de SwingWorkers ... d'où peut-être le blocage ?
    - avez-vous d'autres idées ?

  2. #2
    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 maccormick Voir le message
    - un objet qui contient 2 tableaux de 50000 objets de 10 champs, soit donc un million de champs, c'est trop pour JAVA ?
    Java n'a rien à voir là dedans, cela dépend de la taille des données et de la mémoire disponible pour la JVM...

    Mais bon je ne sais pas si c'est très utile de tout charger en mémoire...

    Citation Envoyé par maccormick Voir le message
    - j'ai abandonné les bases de données (H2) pour faire du tout objet et de la sérialisation car je pensais ça plus souple : faut-il que je fasse marche arrière (ça m'embêterai parce que j'avais eu des soucis de Heap Space avec les bdd) ?
    Pourtant les BDD sont faites pour gérer simplement de grosse quantité de données...

    Citation Envoyé par maccormick Voir le message
    - y-a-t-il d'autres outils (dans Eclipse notamment) qui pourraient me dire ce qui ne va pas ?
    Dans le JDK tu as jvisualvm...

    Citation Envoyé par maccormick Voir le message
    - lorsque je lance plusieurs SwingWorkers à la suite, ils devraient être exécutés les uns à la suite des autres non ? car j'en utilise lors de la sauvegarde (sérialisation) de mes objets, et en fait plusieurs se lancent en même temps (j'ai testé avec des fenêtres de jprogressbar indeterminate et il y en a 2 qui apparaissent en même temps) après le lancement du second processus puis se bloquent (lorsque je lance le 1er, tout va très vite et je n'en voit qu'une !).
    Non par défaut les SwingWorker utilisent un pool de 10 thread max. Donc tu peux avoir 10 SW en même temps.

    Si tu veux éviter cela il faut les lancer via ton propre executor (voir la classe Executors)


    a++

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    116
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 116
    Points : 53
    Points
    53
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    Java n'a rien à voir là dedans, cela dépend de la taille des données et de la mémoire disponible pour la JVM...
    Oui, c'est ce que je voulais dire ...

    Citation Envoyé par adiGuba Voir le message
    Mais bon je ne sais pas si c'est très utile de tout charger en mémoire...
    Pour avoir un affichage fluide, c'est plutôt mieux non ?

    Citation Envoyé par adiGuba Voir le message
    Pourtant les BDD sont faites pour gérer simplement de grosse quantité de données...
    ok, mais j'avais aussi des heap space avec ma BDD

    Citation Envoyé par adiGuba Voir le message
    Dans le JDK tu as jvisualvm...
    oui, j'ai regardé, et je suis bien en heap space, mais ce qui prend le plus de place, ce sont les char, String, int etc ...

    Citation Envoyé par adiGuba Voir le message
    Non par défaut les SwingWorker utilisent un pool de 10 thread max. Donc tu peux avoir 10 SW en même temps.

    Si tu veux éviter cela il faut les lancer via ton propre executor (voir la classe Executors)
    ok, du coup ça doit aller

    Pour la BDD, tu peux me dire en gros à partir de quand, combien tu l'utilises ?

  4. #4
    Membre chevronné
    Inscrit en
    Mai 2006
    Messages
    1 364
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 1 364
    Points : 1 984
    Points
    1 984
    Par défaut
    Citation Envoyé par maccormick Voir le message
    - Lorsque j'ajoute une première liste et que j’extrais pour la première fois mettons 50000 messages, tout se déroule parfaitement, en un peu moins de 10 secondes.
    - Mais lorsque je réitère le processus pour la seconde fois en ajoutant une nouvelle liste avec 50000 Messages, un ralentissement énorme se fait vers 90%.
    - Et lorsque le processus parvient enfin à se terminer, je ne peux même pas dépasser les 2% pour l'ajout d'une troisième liste.
    Ca, ca sent la saturation mémoire ou bien le tri d'une grosse liste pas adaptée.

    Citation Envoyé par maccormick Voir le message
    - un objet qui contient 2 tableaux de 50000 objets de 10 champs, soit donc un million de champs, c'est trop pour JAVA ?
    Comme précisé, ca depend de la taille allouée à ta JVM. Mais dans tous les cas, c'est pas adapté (le probleme que tu rencontres se produit à 50000 messages mais qu'arrivera t-il a 100000 ou bien 150000 messages ?)

    Citation Envoyé par maccormick Voir le message
    - j'ai abandonné les bases de données (H2) pour faire du tout objet et de la sérialisation car je pensais ça plus souple : faut-il que je fasse marche arrière (ça m'embêterai parce que j'avais eu des soucis de Heap Space avec les bdd) ?
    C'est la solution qui te permettrai d'etre sur que ton programme marche quel que soit la quantité de données (et qui en plus est adaptée pour les extraire). Bref, c'est LA solution.

    Citation Envoyé par maccormick Voir le message
    - y-a-t-il d'autres outils (dans Eclipse notamment) qui pourraient me dire ce qui ne va pas ?
    +1 pour jvisualvm qui est pas mal.


    Citation Envoyé par maccormick Voir le message
    - lorsque je lance plusieurs SwingWorkers à la suite, ils devraient être exécutés les uns à la suite des autres non ? car j'en utilise lors de la sauvegarde (sérialisation) de mes objets, et en fait plusieurs se lancent en même temps (j'ai testé avec des fenêtres de jprogressbar indeterminate et il y en a 2 qui apparaissent en même temps) après le lancement du second processus puis se bloquent (lorsque je lance le 1er, tout va très vite et je n'en voit qu'une !).
    Le principe de swing, c'est d'avoir une seule tache (appelée EDT) qui manipule l'ensemble de l'IHM (affichage des composants graphiques et appel des listeners des composants d'interface comme les boutons ou les combos). Pour ne pas ralentir celle-ci, il n'y a pas de protection par semaphore des composants graphiques. C'est pour ca qu'il peut y avoir des exceptions quand tu ajoutes des elements dans une liste dans un thread que tu as créé. swingworker permet d'effectuer un traitement long sans bloquer l'ihm et, eventuellement, de la mettre à jour de temps en temps (principe de la progressbar). Pour finir, quel que soit le nombre de swingworkers utilisés, cette classe te garantie que l'appel des fonctions de l'ihm (cad les fonctions process et done) se fera dans le contexte de la tache EDT (donc par définition pas en meme temps).

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    116
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 116
    Points : 53
    Points
    53
    Par défaut
    Bon, après analyse avec jvisualvm, c'est bien une saturation mémoire, et maintenant après quelques modifs, ça passe en heap space lors de la sérialisation !
    Je vais donc me re-tourner vers H2, et prier pour que ça se passe bien cette fois : j'avais eu des galères avec lorsque je lui donnais un trop grand nombre de données, mais bon, je pense (j'espère ) que c'était un défaut de conception !!!
    Merci et @+

  6. #6
    Membre chevronné
    Inscrit en
    Mai 2006
    Messages
    1 364
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 1 364
    Points : 1 984
    Points
    1 984
    Par défaut
    Une base de données est beaucoup mieux foutue que tout ce que tu pourras faire pour stocker tes données (qui reviendra de toute facon à créer ton propre moteur de BDD, cad réinventer la roue). En plus, il en existe des bien foutues et gratuites (mysql ou hsqldb par exemple). C'est également le meilleur moyen d'etre sur que ton programme fonctionnera encore quand le nombre de messages aura augmenté (par définition, si tu crées des objets, il arrivera toujours un moment ou tu vas saturer ta mémoire). Avec une BDD, le risque est de saturer le disque, ce qui arrivera moins vite

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    s it'as eu des problème de mémoire avec h2 c'est soit

    - que tu a créé une base de données en mémoire, ce qui n'est pas très utilise pour la conservation des données, et ne résoud pas ton problème mémoire
    - soi qu'en plus de les envoyer dans h2 t'a aussi continué à garder tes objet en mémoire.

    H2, avec une empreinte java d'à peine quelques M est capable de gérer des base de plusieurs centaines de milliers de lignes sans soucis. Ne pas oublier de créer les index pour faire des recherches rapides dedans (ça peut faire la différence entre un select de quelques millisecondes et un select de 30 secondes :p )

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    116
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 116
    Points : 53
    Points
    53
    Par défaut
    @hwoarang : oui, c'est vrai, surtout que je commençais justement dans mes traitements à faire des trucs super compliqués qu'un simple SELECT avec ORDER BY réalisait sans problème !

    @tchize_ : salut tchize ! effectivement, je vais revoir ma conception d'appel de mes données. Mais par exemple, j'avais un heap space lorsque je devais mettre en mémoire tous mes messages pour les afficher dans un JTable. Dans ce cas là, je suis bien obligé de faire un SELECT * sur toute ma table non ?

  9. #9
    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
    Citation Envoyé par maccormick Voir le message
    @tchize_ : salut tchize ! effectivement, je vais revoir ma conception d'appel de mes données. Mais par exemple, j'avais un heap space lorsque je devais mettre en mémoire tous mes messages pour les afficher dans un JTable. Dans ce cas là, je suis bien obligé de faire un SELECT * sur toute ma table non ?
    Non...

    Déjà ca m'étonnerait que la JTable affiche toutes les informations des messages, donc autant se limiter à ce que tu affiches. Quittes à refaire un select via index pour afficher le détail du message.

    Ensuite il doit y avoir moyen de ne charger QUE ce qui est affiché au lieu de tout....


    a++

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Si on prend un écran de 1024 pixel de haut et une police de 10 pixels, ta JTable ne saura pas afficher simultanément plus de 103 entrées. Si tu garde une cache pour le défilement, ca te fait à tout casser 2000 entrées à garder en mémoire. On est bien loin des 50.000 ou des 100.000

    Maintenant, à toit de maitriser suffisament JTable pour pouvoir faire du chargement uniquement de ce qui est nécessaire. On ne fait pas une application qui traite et affiche 500M de données comme on fait une application qui traite et afffiche 500k de données

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    116
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 116
    Points : 53
    Points
    53
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Si tu garde une cache pour le défilement, ca te fait à tout casser 2000 entrées à garder en mémoire.
    Très intéressant ça ! Mais totalement nouveau pour moi !
    C'est vrai que mon JTable n'affiche qu'une trentaine de lignes à la fois. Mais j'ai absolument besoin de pouvoir afficher tous les messages pour avoir une vue d'ensemble ... Comment ça se passe la relation JTable / Cache ?

  12. #12
    Membre confirmé Avatar de NeptuS
    Profil pro
    Inscrit en
    Août 2005
    Messages
    392
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2005
    Messages : 392
    Points : 508
    Points
    508
    Par défaut
    Salut,
    Je n'ai pas lu tous les POST, mais les premiers concernaient le stockage.
    As-tu pensé à Hibernate ? La gestion du stockage deviendrai transparente.

    De plus, tu dois pouvoir gérer plus facilement la pagination, il me semble.
    Bon courage.
    Toute vérité est bonne à entendre, même si toutes les vérités ne sont pas bonnes à dire.
    Rien ne sert de partir à point, il vaut mieux courir .

  13. #13
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    116
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 116
    Points : 53
    Points
    53
    Par défaut
    Citation Envoyé par NeptuS Voir le message
    Salut,
    Je n'ai pas lu tous les POST, mais les premiers concernaient le stockage.
    As-tu pensé à Hibernate ? La gestion du stockage deviendrai transparente.
    Oui, j'en entends souvent parler mais je ne me suis jamais penché sur la question ...
    Quel est l'avantage d'utiliser hibernate ? Dans mes souvenirs, ça rajoute surtout une couche non ?

  14. #14
    Membre confirmé Avatar de NeptuS
    Profil pro
    Inscrit en
    Août 2005
    Messages
    392
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2005
    Messages : 392
    Points : 508
    Points
    508
    Par défaut
    Par défaut, tu stocke en base.
    Toute vérité est bonne à entendre, même si toutes les vérités ne sont pas bonnes à dire.
    Rien ne sert de partir à point, il vaut mieux courir .

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Les JTable utilisent un Model en arrière plan, que tu peux passer au constructeur. A charge de ce Model de se débrouiller comme il veux pour fournir à la JTable les row dont elle a besoin, quand elle en a besoin. La JTable ne va, au final, que demander combien il y a des lignes, et, pour les objet visibles dans le défilement, quels ils sont. La JTable ne dessinant jamais les éléments non visibles, elle n'a pas besoin de savoir ce qu'il y a dedans et n'interroge pas le Model à ce propos.

    Maintenant faire un Model de JTable qui pompe progressivement sur une base de donnée, c'est tout un travail, mais on trouve plein de tutos sur le net

  16. #16
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    116
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 116
    Points : 53
    Points
    53
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Les JTable utilisent un Model en arrière plan, que tu peux passer au constructeur. A charge de ce Model de se débrouiller comme il veux pour fournir à la JTable les row dont elle a besoin, quand elle en a besoin. La JTable ne va, au final, que demander combien il y a des lignes, et, pour les objet visibles dans le défilement, quels ils sont. La JTable ne dessinant jamais les éléments non visibles, elle n'a pas besoin de savoir ce qu'il y a dedans et n'interroge pas le Model à ce propos.

    Maintenant faire un Model de JTable qui pompe progressivement sur une base de donnée, c'est tout un travail, mais on trouve plein de tutos sur le net
    ok, j'ai compris le concept !
    et que penses-tu d'hibernate ?

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Hibernate vous permet de traiter facilement vos accès base de données pour les convertir en objet, a vous de voir si vous en avez besoin. C'est un pe ude l'artillerie lourde et ca ne va pas gérer votre problème de mémoire (ça pourrait même l'empirer)

  18. #18
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    116
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 116
    Points : 53
    Points
    53
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Hibernate vous permet de traiter facilement vos accès base de données pour les convertir en objet, a vous de voir si vous en avez besoin. C'est un pe ude l'artillerie lourde et ca ne va pas gérer votre problème de mémoire (ça pourrait même l'empirer)
    ok, merci !

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

Discussions similaires

  1. setInterval qui ralenti lors d'un changement d'onglet
    Par Romaiiiiiin dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 09/05/2015, 15h15
  2. Erreur runtime -2147417843 lors d un second appel de wmi
    Par atc666 dans le forum VB 6 et antérieur
    Réponses: 16
    Dernier message: 27/11/2014, 00h23
  3. procedure stockée qui ralenti pendant son execution
    Par deterred dans le forum SQL Procédural
    Réponses: 0
    Dernier message: 21/08/2009, 08h49
  4. Réponses: 2
    Dernier message: 10/03/2004, 18h52
  5. Réponses: 6
    Dernier message: 27/01/2004, 16h08

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