Précédent   Forum du club des développeurs et IT Pro > Java > Général Java
Général Java Java SE, Java ME, APIs, Persistance, JDBC, Spring, XML. Avant de poster -> FAQ Java, Sources Java
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 14/11/2012, 19h10   #1
Nico2050
Invité de passage
 
Homme Nicolas
Étudiant
Inscription : février 2011
Messages : 7
Détails du profil
Informations personnelles :
Nom : Homme Nicolas
Localisation : Belgique

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : février 2011
Messages : 7
Points : 4
Points : 4
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 :
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
Nico2050 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/11/2012, 20h54   #2
OcterA
Membre actif
 
Homme
Ingénieur développement logiciels
Inscription : avril 2007
Messages : 106
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 25
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 : 106
Points : 194
Points : 194
Salut,
Au lieu de faire ton img = null à la fin, essaie un img.flush()
__________________

Mon petit blog sans prétention : http://blog.octera.info/
OcterA est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/11/2012, 22h21   #3
Nico2050
Invité de passage
 
Homme Nicolas
Étudiant
Inscription : février 2011
Messages : 7
Détails du profil
Informations personnelles :
Nom : Homme Nicolas
Localisation : Belgique

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : février 2011
Messages : 7
Points : 4
Points : 4
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ù)
Nico2050 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/11/2012, 22h46   #4
tchize_
Expert Confirmé Sénior
 
Avatar de tchize_
 
Homme
Responsable de service informatique
Inscription : avril 2007
Messages : 18 287
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 33
Localisation : Belgique

Informations professionnelles :
Activité : Responsable de service informatique
Secteur : Service public

Informations forums :
Inscription : avril 2007
Messages : 18 287
Points : 32 766
Points : 32 766
Envoyer un message via MSN à tchize_ Envoyer un message via Skype™ à tchize_
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)
__________________
⥀⥁ Чиз faq java, cours java, javadoc. Pensez à et
Laisse entrer le jour après une nuit sombre. Si tu es toujours là, tu n'es pas faite pour mourir.
tchize_ est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 15/11/2012, 00h21   #5
Nico2050
Invité de passage
 
Homme Nicolas
Étudiant
Inscription : février 2011
Messages : 7
Détails du profil
Informations personnelles :
Nom : Homme Nicolas
Localisation : Belgique

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : février 2011
Messages : 7
Points : 4
Points : 4
Merci, ça consomme déjà beaucoup moins

Le problème vient bien du fait que

Code :
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 :
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;
Nico2050 est déconnecté   Envoyer un message privé Réponse avec citation 10
Réponse Cette discussion est résolue.
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 01h05.


 
 
 
 
Partenaires

Hébergement Web