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 :

Garbage Collector ne libère pas de mémoire


Sujet :

Java

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2011
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2011
    Messages : 8
    Points : 11
    Points
    11
    Par défaut Garbage Collector ne libère pas de mémoire
    Bonjour,

    Je suis assez embêté par un petit problème.
    J'essaye de coder un programme qui va rechercher des images (format jpeg, png, ...) sur le disque et qui crée des icones miniatures pour les afficher.

    Ma démarche est la suivante: j'ouvre l'image dans un "BufferedImage", je calcule la futur taille de la miniature puis je met cette miniature dans un ImageIcon.

    Voici la fonction qui effectue cette tâche.

    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
    37
    38
     
    public ImageIcon getTiny(int maxWidth, int maxHeight) throws IOException
    {
    	BufferedImage img = null;
    	File fi = new File(_path);
    	if (fi.exists() && fi.isFile() && fi.canRead())
    	{
    		img = ImageIO.read(fi);
    		if (img == null)
    		{
    			throw new IOException("Le fichier \"" + fi.getName() + "\" est illisible");
    		}
    	}
    	else
    	{
    		throw new IOException("Impossible d'ouvrir le fichier \"" + _path +"\"");
    	}
     
    	int wid = img.getWidth();
    	int hei = img.getHeight();
    	float ratio = (float) wid / hei;
    	if (wid >= hei)
    	{
    		wid = maxWidth;
    		hei = (int) (maxWidth / ratio);
    	}
    	else
    	{
    		hei = maxHeight;
    		wid = (int) (maxHeight * ratio);
    	}
    	ImageIcon imIcon = new ImageIcon(img.getScaledInstance(wid, hei,java.awt.Image.SCALE_SMOOTH));
     
    	img = null;
    	System.gc(); // J'essaye de forcer le Garbage collector à nettoyer (mais ça ne marche pas)
     
    	return imIcon;
    }
    Lorsque j'essaye de créer une vingtaine de miniatures (taille maximum 100*100 la miniature) le programme se met à consommer plus de 500 Mo de mémoire.

    J'en déduit donc que le garbage collector ne nettoie pas les bufferedImage (qui contiennent de images assez grandes) malgré mes tentatvies pour forcer la désallocation de mémoire

    Si quelqu'un a une idée je suis preneur

    Merci d'avance

  2. #2
    Membre actif
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    117
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Isère (Rhône Alpes)

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 117
    Points : 219
    Points
    219
    Par défaut
    Salut,
    Au lieu de faire ton img = null à la fin, essaie un img.flush()

    Mon petit blog sans prétention : http://blog.octera.info/

  3. #3
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2011
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2011
    Messages : 8
    Points : 11
    Points
    11
    Par défaut
    Malheureusement ça n'a pas l'air de marcher beaucoup mieux
    Mais merci quand même pour la réponse

    PS: Je ne l'ai pas dit plus haut mais j'utilise java 1.6 (juste au cas où)

  4. #4
    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
    le System.gc, tu oublie tout de suite ue ça existe, car ça ne fais pas ce que tu veux. Si tu as un out of memory, c'est que le garbage collector a déjà nettoyé et qu'il n'a plsu rien trouvé de récupérable.

    Dans ton cas, tu utilise image.getScaledInstance(). La doc sous entends que cette image réduit ne fait que dessiner l'image principale à une taille plus petite => Elle garde une référence vers l'image principale.

    Crée toi même une nouvelle BufferedImage plus petite et utilise les méthodes de la classe Graphics2D pour dessiner une fois pour toute la grande dans la petite.

    (appel à graphics.drawImage prenant en paramèter un AffineTransform pour la dessiner)

  5. #5
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2011
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2011
    Messages : 8
    Points : 11
    Points
    11
    Par défaut
    Merci, ça consomme déjà beaucoup moins

    Le problème vient bien du fait que

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ImageIcon imIcon = new ImageIcon(img.getScaledInstance(wid, hei,java.awt.Image.SCALE_SMOOTH));
    garde une référence vers la "grande" image ce qui empêche au garbage collector de faire son boulot

    Si quelqu'un se retrouve confronté un problème similaire, voici comment j'ai implémenté la création de l'image réduite:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    // La grande image est la variable "img"
    BufferedImage smaller = new BufferedImage(wid, hei,BufferedImage.TYPE_INT_ARGB);
    Graphics2D graph = smaller.createGraphics();
    graph.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
    graph.drawImage(img, 0, 0, wid, hei, null);
    graph.dispose();
    ImageIcon imIcon = new ImageIcon(smaller);
    img = null;

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

Discussions similaires

  1. [Windows] Free ne libère pas la mémoire
    Par Higgins dans le forum Composants FMX
    Réponses: 9
    Dernier message: 15/06/2015, 16h42
  2. Réponses: 7
    Dernier message: 13/08/2014, 17h57
  3. Le garbage collector me laisse pas la main
    Par Franck.H dans le forum VB.NET
    Réponses: 0
    Dernier message: 02/10/2013, 09h04
  4. mqsvc.exe ne libère pas sa mémoire
    Par Kagozuma dans le forum Général Dotnet
    Réponses: 6
    Dernier message: 12/08/2011, 12h39
  5. Réponses: 18
    Dernier message: 08/04/2009, 10h19

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