COMMENT " REUSSIR " DES FUITES MEMOIRES EN JAVA?



Documents pareils
Remote Method Invocation (RMI)

TD Objets distribués n 3 : Windows XP et Visual Studio.NET. Introduction à.net Remoting

Programmation Réseau. Sécurité Java. UFR Informatique jeudi 4 avril 13

RMI. Remote Method Invocation: permet d'invoquer des méthodes d'objets distants.

Corrigé des exercices sur les références

Exceptions. 1 Entrées/sorties. Objectif. Manipuler les exceptions ;

Page 1 sur 5 TP3. Thèmes du TP : l la classe Object. l Vector<T> l tutorial Interfaces. l Stack<T>

La JVM. La machine virtuelle Java. La JVM. La JVM

Java DataBaseConnectivity

Java Licence Professionnelle CISII,

TP n 2 Concepts de la programmation Objets Master 1 mention IL, semestre 2 Le type Abstrait Pile

Cours intensif Java. 1er cours: de C à Java. Enrica DUCHI LIAFA, Paris 7. Septembre Enrica.Duchi@liafa.jussieu.fr

TP1 : Initiation à Java et Eclipse

RMI le langage Java XII-1 JMF

TP1 : Initiation à Java et Eclipse

Initiation à JAVA et à la programmation objet.

Un ordonnanceur stupide

Plan du cours. Historique du langage Nouveautés de Java 7

Synchro et Threads Java TM

Remote Method Invocation Les classes implémentant Serializable

Structure d un programme et Compilation Notions de classe et d objet Syntaxe

Programme Compte bancaire (code)

API04 Contribution. Apache Hadoop: Présentation et application dans le domaine des Data Warehouses. Introduction. Architecture

Premiers Pas en Programmation Objet : les Classes et les Objets

as Architecture des Systèmes d Information

Introduction à Java. Matthieu Herrb CNRS-LAAS. Mars

Pour signifier qu'une classe fille hérite d'une classe mère, on utilise le mot clé extends class fille extends mère

Java - la plateforme

TD3: tableaux avancées, première classe et chaînes

Projet de programmation (IK3) : TP n 1 Correction

Threads. Threads. USTL routier 1

Chapitre 2. Classes et objets

Auto-évaluation Programmation en Java

Machines Virtuelles. et bazard autour. Rémi Forax

Conception de serveurs d'applications ouverts

Serveur d'archivage 2007 Installation et utilisation de la BD exist

Héritage presque multiple en Java (1/2)

ACTIVITÉ DE PROGRAMMATION

Java Licence Professionnelle CISII,

Langage Java. Classe de première SI

Eclipse atelier Java

1 Définition d une classe en Java

Cours 1: Java et les objets

IFT287 Exploitation de base de données relationnelles et orientées objet. Laboratoire Mon premier programme Java en Eclipse

Programmation Objet Java Correction

TP1. Outils Java Eléments de correction

Derrière toi Une machine virtuelle!

La persistance des données dans les applications : DAO, JPA, Hibernate... COMPIL 2010 francois.jannin@inp-toulouse.fr 1

LMI 2. Programmation Orientée Objet POO - Cours 9. Said Jabbour. jabbour@cril.univ-artois.fr

Info0101 Intro. à l'algorithmique et à la programmation. Cours 3. Le langage Java

Programmer en JAVA. par Tama

Calcul Parallèle. Cours 5 - JAVA RMI

Bases du langage. Historique Applications et applets Éléments de base du langage Classes et objets Les exceptions

TP, première séquence d exercices.

Pour plus de détails concernant le protocole TCP conférez vous à la présentation des protocoles Internet enseignée pendant.

Manuel d implémentation des Web Services Sous Axis1 et Axis2/Tomcat/linux. Par Pr Bouabid EL OUAHIDI

TD/TP PAC - Programmation n 3

Programmation par les Objets en Java

Généralités sur le Langage Java et éléments syntaxiques.

Introduction : les processus. Introduction : les threads. Plan

Corrigés des premiers exercices sur les classes

Projet gestion d'objets dupliqués

Introduction au langage Java

Tp 1 correction. Structures de données (IF2)

Polycopié Cours Programmation Orientée Objet sous Java Programme : Filière SMI S5

Intergiciel - concepts de base

Programmation Orientée Objet

Le MSMQ. Version 1.0. Pierre-Franck Chauvet

Chapitre I Notions de base et outils de travail

Création d objet imbriqué sous PowerShell.

OS Réseaux et Programmation Système - C5

Java Licence Professionnelle CISII, Cours 2 : Classes et Objets

Applet pour visualiser les variables «automate» notifiées

Interfaces graphiques avec l API Swing

PROGRAMMATION PAR OBJETS

INTRODUCTION A JAVA. Fichier en langage machine Exécutable

Encapsulation. L'encapsulation consiste à rendre les membres d'un objet plus ou moins visibles pour les autres objets.

Cahier des Charges du Projet Domotique. Choquet Mathieu Masson Jérôme Groupe 6. Domotique. p.1

Traitement de données

Une introduction à Java

Package Java.util Classe générique

Licence Bio Informatique Année Premiers pas. Exercice 1 Hello World parce qu il faut bien commencer par quelque chose...

Communication inter-processus (IPC) : tubes & sockets. exemples en C et en Java. F. Butelle

TP3. Mail. Attention aux fausses manoeuvres lors de ce TP vous pouvez endommager votre mail sur ouindose.

P r ob lé m a t iq u e d e la g é n é r icit é. Pr in cip e d e la g é n é r icit é e n Ja v a ( 1 /3 )

Cours 1 : Introduction. Langages objets. but du module. contrôle des connaissances. Pourquoi Java? présentation du module. Présentation de Java

1. Structure d un programme C. 2. Commentaire: /*..texte */ On utilise aussi le commentaire du C++ qui est valable pour C: 3.

La base de données XML exist. A. Belaïd

Flux de données Lecture/Ecriture Fichiers

Présentation de Java. Olivier de Pertat IT GROUP

Info0604 Programmation multi-threadée. Cours 5. Programmation multi-threadée en Java

Programmation avancée et répartie en Java : interfaçage avec d autres langages

RN2-Programmation Orientée Objet - JAVA CH 1 Introduction à la POO et Java

Exclusion Mutuelle. Arnaud Labourel Courriel : arnaud.labourel@lif.univ-mrs.fr. Université de Provence. 9 février 2011

Java 7 Les fondamentaux du langage Java

Gestion distribuée (par sockets) de banque en Java

Conventions d écriture et outils de mise au point

Création d un service web avec NetBeans 5.5 et SJAS 9

TP Composants Java ME - Java EE. Le serveur GereCompteBancaireServlet

Chapitre 10. Les interfaces Comparable et Comparator 1

Transcription:

page : 1/19 COMMENT " REUSSIR " DES FUITES MEMOIRES EN JAVA? Date 05/12/08 Version Modification Author V1.0 Initial JL PASTUREL

page : 2/19 Table des matières 1 INTRODUCTION... 3 2 CLASSES DE TESTS... 3 2.1 Classe initiale avec fuite mémoire... 3 3 Génération fuite mémoire...4 3.1 Lancement application...4 3.2 Analyse avec Java VisualVM... 4 3.3 Conclusion... 6 4 CORRECTION DE LA FUITE MEMOIRE...6 4.1 Source classe corrigée...6 4.2 Lancement de l application...7 4.3 Analyse Java VisualVM... 8 4.4 Conclusion test NoMemoryLeak1... 9 5 OUI MAIS AVEC LES WEAKREFERENCE?... 9 5.1 Source classe...9 5.2 Lancement de l application...10 5.3 Analyse Java VisualVM... 10 5.4 Conclusion test MemoryLeak2...13 6 SOLUTION : java.util.weakhashmap... 13 6.1 La classe sans fuite mémoire NoMemoryLeak2...13 6.2 Lancement de l application...14 6.3 Analyse Java VisualVM... 14 6.4 Conclusion test NoMemoryLeak2... 15 7 Et si je dé-référence directement la Collection?...15 7.1 Source MemoryLeak3...16 7.2 Lancement de l application...17 7.3 Analyse Java VisualVM... 17 7.4 Conclusion test MemoryLeak3...18

page : 3/19 1 INTRODUCTION Le but de ce petit document est de montrer comment on peut générer des fuites mémoires en java en utilisant des Collections d objets. La JVM utilisée pour cette démonstration est la JVM HostSpot de SUN 1.6.0_10 sur Windows XP. Le suivi d occupation de la heap sera fait à l aide de l outil Java VisualVM fournie avec cette version. L outil intègre aussi un profiler 2 CLASSES DE TESTS Nous allons nous appuyer sur des classes simples, sans signification fonctionnelle réelle. 2.1 Classe initiale avec fuite mémoire La classe principale : MemoryLeak.java : import java.util.arraylist; public class MemoryLeak /** * @param args */ public ArrayList<Bourrage> listbourrage= new ArrayList<Bourrage>(); public void dosomething(string name) Bourrage bour=new Bourrage(name); listbourrage.add(bour); // Faire des choses avec bour bour=null; // Ne sert à rien, pour montre seulement que bour est bien de-reference ; public static void main(string[] args) // TODO Auto-generated method stub // On va creer la fuite MemoryLeak memleak=new MemoryLeak(); int nbboucles = Integer.parseInt(args[0]); for ( int i=0;i<nbboucles;i++ ) memleak.dosomething(args[1]); try Thread.sleep(10); catch (InterruptedException e) // TODO Auto-generated catch block

page : 4/19 e.printstacktrace(); La classe auxiliaire Bourrage.java : public class Bourrage // Un simble String public String name="monnom" ; public Bourrage(String _name) name=_name; 3 Génération fuite mémoire 3.1 Lancement application L application est lancée avec les paramètres suivants : C:\eclipse\workspace\\bin>java -Xms2M -Xmx2M MemoryLeak 10000000 tttyttttttttytttthhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhttttttttttttttt 3.2 Analyse avec Java VisualVM La console Java VisualVM donne :

page : 5/19 Le diagramme en haut à gauche montre l effet de la fuite mémoire. La mémoire résiduelle après Garbage a tendance à monter au fur et à mesure de la vie de l application. On notera aussi que malgré le paramètre -Xmx à 2Mo la heap de l JVM continue à grandir au delà des 2Mo.

page : 6/19 1 heure après : 3.3 Conclusion Lors d un dé-référencement d objet contenu dans une Collection, il faut aussi le retirer de la Collection sinon fuite mémoire garantie. L objet ArrayList garde dans sa collection une seconde Strong Reference de l objet Bourrage. Un objet n est garbageable que si toutes ses Strong ( Hard) References sont à null. 4 CORRECTION DE LA FUITE MEMOIRE 4.1 Source classe corrigée NoMemoryLeak1.java : import java.util.arraylist;

page : 7/19 public class NoMemoryLeak1 /** * @param args */ public ArrayList<Bourrage> listbourrage= new ArrayList<Bourrage>(); public void dosomething(string name) Bourrage bour=new Bourrage(name); listbourrage.add(bour); // Faire des choses avec bour // ici ce coup-ci on retire bour de la Collection : listbourrage.remove(bour); bour=null; // Ne sert à rien, pour montre seulement que bour est bien de-reference ; public static void main(string[] args) // TODO Auto-generated method stub // On va creer la fuite NoMemoryLeak1 nomemleak=new NoMemoryLeak1(); int nbboucles = Integer.parseInt(args[0]); for ( int i=0;i<nbboucles;i++ ) nomemleak.dosomething(args[1]); try Thread.sleep(10); catch (InterruptedException e) // TODO Auto-generated catch block e.printstacktrace(); Noter en gras la suppression de l objet de la collection avant son dé-référencement. 4.2 Lancement de l application C:\eclipse\workspace\\bin>java -Xms2M -Xmx2M NoMemoryLeak1 10000000 tt tyttttttttytttthhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhttttttttttttttt

page : 8/19 4.3 Analyse Java VisualVM Sur ce test, on voit sur le diagramme en haut à gauche qu il n y a plus de fuite mémoire car la taille de la mémoire résiduelle après provocation d un Full GC n augmente plus. Le nombre d objets Bourrage en vie est aussi réduit par rapport au tir précédent.

page : 9/19 4.4 Conclusion test NoMemoryLeak1 La suppression de l objet Bourrage de la Collection a permis de supprimer la fuite mémoire. 5 OUI MAIS AVEC LES WEAKREFERENCE? Pour cet test de la fuite mémoire nous allons utiliser le mécanisme des références faibles proposées par Java. Ici nous utiliserons une WeakReference. Pour plus d information en français : http://gfx.developpez.com/tutoriel/java/reference-memoire/ http://blog.developpez.com/adiguba?title=comprendre_les_references_en_java 5.1 Source classe MemoryLeak2.java : import java.lang.ref.weakreference; import java.util.arraylist; public class MemoryLeak2 /** * @param args */ // La Collection ArrayList ne contient que des WeakReference public ArrayList<WeakReference<Bourrage>> listbourrage= new ArrayList<WeakReference<Bourrage>>(); public void dosomething(string name) Bourrage bour=new Bourrage(name); // Utilisation Avancée // Creation d'une WeakReference sur l'objet bour WeakReference<Bourrage> wrbour=new WeakReference<Bourrage>(bour); // On met la weakreference dans la collection à la place de la Strong Reference listbourrage.add(wrbour); // Faire des choses avec bour bour=null; // Ne sert à rien, pour montre seulement que bour est bien de-reference ; public static void main(string[] args)

page : 10/19 // TODO Auto-generated method stub // On va creer la fuite MemoryLeak2 memleak=new MemoryLeak2(); int nbboucles = Integer.parseInt(args[0]); for ( int i=0;i<nbboucles;i++ ) memleak.dosomething(args[1]); try Thread.sleep(10); catch (InterruptedException e) // TODO Auto-generated catch block e.printstacktrace(); Noter en gras l'utilisation de l ArrayList de WeakReference sur l objet Bourrage 5.2 Lancement de l application C:\eclipse\workspace\\bin>java -Xms2M -Xmx2M MemoryLeak2 10000000 tt tyttttttttytttthhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhttttttttttttttt 5.3 Analyse Java VisualVM Ben on a toujours des fuites mémoires malgré l utilisation de WeakRreference.

page : 11/19

page : 12/19

page : 13/19 Le nombre de WeakReference augmente comme lors du premier test avec l objet Bourrage.. 5.4 Conclusion test MemoryLeak2 Le remplacement de la référence Strong (Hard) par une référence plus faible sur l objet dans la Collection ArrayList n a pas permis d éliminer la fuite mémoire. L objet WeakReference a lui même une Strong Reference, on retombe sur le même problème que lors du test initial. Je laisse au lecteur le soin de corriger le code en supprimant la Weak référence de la structure ArrayList comme vue lors de la première Collection. Ceci est lié au fait que l Objet ArrayList ne gère pas le fait que son contenu est de type Reference faible. Pour cela, il faut utiliser une autre type de Collection : java.util.weakhashmap 6 SOLUTION : java.util.weakhashmap La classe java.util.weakhashmap contient des couples clé/valeur en utilisant des références faibles sur la clé seulement, donc si la clé n'est plus référencée par une référence forte ailleurs dans le programme, le couple est automatiquement supprimé de la collection. 6.1 La classe sans fuite mémoire NoMemoryLeak2 Donc en gérant les référence de Bourrage dans l objet java.util.weakhashmap. NoMemoryLeak2.java : import java.util.weakhashmap; public class NoMemoryLeak2 // pour servir de clé à WeakHashMap static Long index=0l; /** * @param args */ // public ArrayList<Bourrage> listbourrage= new ArrayList<Bourrage>(); // Remplacement par l'objet java.util.weakhashmap public WeakHashMap whmbourrage= new WeakHashMap(); public void dosomething(string name) Bourrage bour=new Bourrage(name); whmbourrage.put(index,bour);

page : 14/19 index++; // Faire des choses avec bour bour=null; // Ne sert à rien, pour montre seulement que bour est bien de-reference ; public static void main(string[] args) NoMemoryLeak2 nomemleak=new NoMemoryLeak2(); int nbboucles = Integer.parseInt(args[0]); for ( int i=0;i<nbboucles;i++ ) nomemleak.dosomething(args[1]); try Thread.sleep(10); catch (InterruptedException e) // TODO Auto-generated catch block e.printstacktrace(); 6.2 Lancement de l application C:\eclipse\workspace\\bin>java -Xms2M -Xmx2M NoMemoryLeak2 10000000 tt tyttttttttytttthhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhttttttttttttttt

page : 15/19 6.3 Analyse Java VisualVM Le diagramme du haut à gauche montre qu il n y a pas de fuite mémoire

page : 16/19 L historique des objets Bourrage montre qu il sont bien garbagés ( trait rouge) et ne contribue pas à la fuite mémoire. 6.4 Conclusion test NoMemoryLeak2 L utilisation de l objet WeakHashMap permet d éviter les fuites mémoires sans avoir à supprimer explicitement l objet dans la Collection. 7 Et si je dé-référence directement la Collection? Il s agit de vérifier que lorsque je positionne à null la référence de l objet ArrayList, les Strong (Hard) Références contenues sont éligibles au garbage. 7.1 Source NoMemoryLeak4 NoMemoryLeak4.java :

page : 17/19 import java.util.arraylist; public class MemoryLeak4 /** * @param args */ public ArrayList<Bourrage> listbourrage= new ArrayList<Bourrage>(); public void dosomething(string name) Bourrage bour=new Bourrage(name); listbourrage.add(bour); // Faire des choses avec bour bour=null; // Ne sert à rien, pour montre seulement que bour est bien de-reference ; public static void main(string[] args) // TODO Auto-generated method stub // On va creer la fuite NoMemoryLeak4 nomemleak=new NoMemoryLeak4(); int nbboucles = Integer.parseInt(args[0]); for ( int i=0;i<nbboucles;i++ ) // Toutes les 1000 boucles on supprime et recrée la Collection ArrayList if(i%1000==0) nomemleak.listbourrage=null; nomemleak.listbourrage= new ArrayList<Bourrage>(); nomemleak.dosomething(args[1]); try Thread.sleep(10); catch (InterruptedException e) // TODO Auto-generated catch block e.printstacktrace(); Remarque : Il est évident que fonctionnellement et d un point de vue " best practice " ce code n a pas lieu d être dans une aucune application digne de ce nom.. Noter en gras, le dé-référencement toutes les 1000 lignes de l Objet ArrayList. 7.2 Lancement de l application C:\eclipse\workspace\\bin>java -Xms2M -Xmx2M NoMemoryLeak4 10000000 tt tyttttttttytttthhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhttttttttttttttt

page : 18/19 7.3 Analyse Java VisualVM Le diagramme du haut à gauche montre que lors des Full Garbage Collector la taille de la mémoire résiduelle revient au même niveau. Et en suivant l historique de la classe Bourrage, on constate bien que les instances sont bien garbagées.

page : 19/19 Les objets Bourrage sont bien garbagés. Remarque : Le nom de la classe n est donc pas correct puisqu il n y pas de fuite mémoire. On la renommera NoMemoryLeak4.java 7.4 Conclusion test NoMemoryLeak4 Le dé-référencement d un objet Collection ( Conteneur) dé-référence les objets qu il contient.