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

Interfaces Graphiques en Java Discussion :

[Image]Liberation des ressources


Sujet :

Interfaces Graphiques en Java

  1. #1
    Membre confirmé
    Inscrit en
    Juillet 2002
    Messages
    194
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 194
    Par défaut [Image]Liberation des ressources
    Bonjour,

    Je développe un programme permettant de visualiser des photos sous forme de diaporama mais j'ai un gros probleme d'occupation mémoire.
    Je charge mes images avec les méthode de la classe ImageIO, je les affiche dans un JPanel, et dès qu'une image n'est plus affichée, je libère (ou plutot je pensais libérer) ses ressources en appelant la méthode flush et en mettant sa référence à null.
    Le probleme c'est que la mémoire n'est aboslument pas libérée et au bout d'une cinquantaine d'images j'ai systematiquement une OutOfMemoryError.

    Comment faire pour libérer correctement la mémoire occupée par une BufferedImage ??

  2. #2
    Expert confirmé
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Par défaut
    Garde la référence sur ta BufferedImage et sette la à null quand le besoin s'en fait sentir

  3. #3
    Membre confirmé
    Inscrit en
    Juillet 2002
    Messages
    194
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 194
    Par défaut
    ben oui c'est bien ce que je fais, dès que l'image n'est plus affichée, je la met à null.

  4. #4
    Membre confirmé
    Inscrit en
    Juillet 2002
    Messages
    194
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 194
    Par défaut
    j'ai essayé tout l'aprem en faisant des null, des flush, des dispose de partout, des appels explicite au gc et pas moyen, toujours cette conso mémoire qui augmente inexorablement!!

    je crois que je vais laissé tomber le java pour cette appli et repasser en C++ car en plus je trouve la classe ImageIO particulierement "moisie". C'est lent, ca consomme un max de mémoire sans jamais pouvoir la libérer et elle ne charge pas toujours correctement certains format d'image comme les gif animés.

  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,


    On pourrais voir un peu de code (comment tu charges les images, comment tu les affiches, et comment tu les "libères").

    a++

  6. #6
    Membre confirmé
    Inscrit en
    Juillet 2002
    Messages
    194
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 194
    Par défaut
    Voila un extrait (j'ai mis que les parties qui concerne l'affichage des images)

    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
     
    public class PanelImage extends JPanel
    {
        private BufferedImage image;
     
        public void setImage(String strChemin)
        {
            if(image != null)
            {
                image.flush();
                image = null;
            }
            try
            {
                image = ImageIO.read(new File(strChemin));
            }
            catch (IOException e)
            {
              ...
            }
        }
     
     
        protected void paintComponent(Graphics g)
        {
            super.paintComponent(g);
            ...
            if(image != null)
            {
                 g.drawImage(image,0,0, null);
            }
            ...
            g.dispose();
        }
     
    }

  7. #7
    Membre confirmé
    Inscrit en
    Juillet 2002
    Messages
    194
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 194
    Par défaut
    J'ai essayé d'utiliser des images "compatibles" (qui sont censées etre optimisées pour la carte graphique) comme il est souvent recommandé de le faire dans ce forum. mais c'est encore pire, j'arrive deux fois plus vite à un dépassement mémoire.
    personne n'a une idée ? j'ai oublié quelque chose ?

  8. #8
    Membre éprouvé
    Profil pro
    Étudiant
    Inscrit en
    Mai 2006
    Messages
    104
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2006
    Messages : 104
    Par défaut
    salut ! plutôt que d'étendre jpanel, essaie plutôt avec jcomponent tu devrais gagner un peu de ressources... sinon on voit pas la façon font tu 'efface' tes images de la mémoire...
    sinon ce qui serait pas mal c'est d'utiliser des images miniatures plutôt que des images en grande résolution qui prennent beaucoup plus de place... tu conserve l'adresse dans un tableau et tu la charge en grande résolution des que tu as besoin

  9. #9
    Membre confirmé
    Inscrit en
    Juillet 2002
    Messages
    194
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 194
    Par défaut
    Citation Envoyé par rom1dep
    ... sinon on voit pas la façon font tu 'efface' tes images de la mémoire...
    ben si tout est dans le setImage... je met la référence à null et je fais un flush (qui ne sert à rien puisque cette méthode est redéfinit dans la classe BufferedImage et qu'elle est vide). Mais la mémoire n'est pas libérée.

    Citation Envoyé par rom1dep
    sinon ce qui serait pas mal c'est d'utiliser des images miniatures plutôt que des images en grande résolution qui prennent beaucoup plus de place... tu conserve l'adresse dans un tableau et tu la charge en grande résolution des que tu as besoin
    Ca ne marche pas dans mon cas car des que je charge une image je l'affiche en "grande résolution".

  10. #10
    Membre Expert
    Homme Profil pro
    Directeur technique
    Inscrit en
    Janvier 2007
    Messages
    1 348
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 348
    Par défaut
    Tu as essayé de lancer ta jvm avec ""-verbose:gc" pour voir ce qu'il se passe ?

  11. #11
    Membre confirmé
    Inscrit en
    Juillet 2002
    Messages
    194
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 194
    Par défaut
    oui et j'ai même placé des notif dans une ReferenceQueue() dans laquelle je stocke les références sur mes images et la garbage collector finalise bien les images mais les ressources ne sont pas libérées !

    J'ai malheureusement bien peur que ca ne vienne pas de mon code, en cherchant un peu sur Internet j'ai des dizaines de post traitant du même probleme.

  12. #12
    Gfx
    Gfx est déconnecté
    Expert confirmé
    Avatar de Gfx
    Inscrit en
    Mai 2005
    Messages
    1 770
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Mai 2005
    Messages : 1 770
    Par défaut
    Note que ton dispose() sur le Graphics g peut causer de gros problèmes de dessin.

  13. #13
    Membre confirmé
    Inscrit en
    Juillet 2002
    Messages
    194
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 194
    Par défaut
    c'est contradictoire avec ce que j'ai lu dans de nombreux post sur ce forum où l'appel à dispose() était fortemment recommandé... mais soit, je te fais entierement confiance sur ce point.
    Cela dit, ça ne résoud malheureusement en rien mon problème initial, je n'arrive tjs pas à libérer les ressouces de mes BufferedImage. une idée ?

  14. #14
    Gfx
    Gfx est déconnecté
    Expert confirmé
    Avatar de Gfx
    Inscrit en
    Mai 2005
    Messages
    1 770
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Mai 2005
    Messages : 1 770
    Par défaut
    Non ce n'est pas contradictoire. On appelle dispose() quand on crée un *nouveau* Graphics (avec par exemple g.create()).

  15. #15
    Membre confirmé
    Inscrit en
    Juillet 2002
    Messages
    194
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 194
    Par défaut
    et sur une BufferedImage, ça a un interet de faire un dispose() sur le Graphics de l'image ? vu que la méthode flush() est redéfinie et ne fait rien.

  16. #16
    Gfx
    Gfx est déconnecté
    Expert confirmé
    Avatar de Gfx
    Inscrit en
    Mai 2005
    Messages
    1 770
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Mai 2005
    Messages : 1 770
    Par défaut
    Ça a un intérêt oui, mais ça ne réglera pas ton problème.

  17. #17
    Membre émérite
    Profil pro
    Inscrit en
    Février 2007
    Messages
    572
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Février 2007
    Messages : 572
    Par défaut
    En fait, flush() dans le cas d'une BufferedImage ne libere pas les data principales de l'image (seulement les informations en cache).

    Pour liberer completement l'image, il faut donc supprimer toutes les references à l'image, et le gc se chargera de faire le menage.

    Faire un dispose sur un Graphics créé à partir d'une BufferedImage permet de couper le lien que possede le Graphics sur la BufferedImage. Mais le plus simple, le plus sur, c'est simplement de mettre le graphics à null (il ne sert plus a rien si tu n'utilises plus l'image).

  18. #18
    Membre confirmé
    Inscrit en
    Septembre 2005
    Messages
    82
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 82
    Par défaut
    Est ce que c'est dans une applet sous IE ?
    Dans ce cas, ce ne serait pas plutot un pb IE ?

    J'ai un comportement similaire et la mémoire n'est meme pas libérée quand je quitte l'applet.

    ++H

  19. #19
    Membre confirmé
    Inscrit en
    Juillet 2002
    Messages
    194
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 194
    Par défaut
    Citation Envoyé par Bighobbit
    Est ce que c'est dans une applet sous IE ?
    Dans ce cas, ce ne serait pas plutot un pb IE ?

    J'ai un comportement similaire et la mémoire n'est meme pas libérée quand je quitte l'applet.

    ++H
    non c'est une appli desktop.

    Pour liberer completement l'image, il faut donc supprimer toutes les references à l'image, et le gc se chargera de faire le menage.
    ben non justement, c'est bien la mon probleme, le gc passe bien sur mon image mais les ressources ne sont pas libérées, j'ai une OutOfMemoryException qui pete apres le chargement de quelques images.

    Visiblement je ne suis pas le seul à avoir constaté le pb :
    http://lists.apple.com/archives/Java.../msg00385.html

  20. #20
    Membre émérite
    Profil pro
    Inscrit en
    Février 2007
    Messages
    572
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Février 2007
    Messages : 572
    Par défaut
    Quelqu'un a eu recemment le même probleme que toi (cf ici)

    Du coup, j'ai fait un test élémentaire. J'ai affiché dans un JInternalFrame une image (de type BufferedImage). A la fermeture de la frame, j'ai libéré l'image (en mettant la reference a null).
    J'ai bien constaté, en mesurant la mémoire utilisée, que l'image était libérée.

    J'ai fait ce test avec la version 6 de java, sous windows.

Discussions similaires

  1. Image issue des ressources de l'application
    Par rtg57 dans le forum Jasper
    Réponses: 2
    Dernier message: 14/05/2015, 07h42
  2. Image à partir des ressources
    Par Bernard B dans le forum Langage
    Réponses: 3
    Dernier message: 09/01/2012, 17h59
  3. Internationalisation d'image avec des ressources
    Par diab_olik dans le forum AWT/Swing
    Réponses: 1
    Dernier message: 07/04/2010, 05h44
  4. Réponses: 4
    Dernier message: 14/10/2003, 08h58

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