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

avec Java Discussion :

Réalise une action à chaque destruction d'une instance d'une classe


Sujet :

avec Java

  1. #1
    Candidat au Club
    Inscrit en
    Juillet 2010
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Juillet 2010
    Messages : 4
    Points : 3
    Points
    3
    Par défaut Réalise une action à chaque destruction d'une instance d'une classe
    Bonjour,

    une petite question : supposons un programme Java, dans lequel j'implémente une classe "maClasse". Supposons aussi que pour une raison quelconque je souhaite connaitre le nombre d'instance de ma classe. Bien entendu je n'ai pas envie d'avoir un compteur manuel que j'incrémente et décrémente moi même au grès des créations / suppressions des instances de maClasse (typiquement dans des boucle for, etc.). Je pensais donc "simplement" mettre dans maClasse un attribut nbInstance :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    static int nbInstance ;
    et dans les constructeurs de maClasse, j'incrémente nbInstance. Voila qui permet de suivre le nombre de créations d'instances de maClasse sans intervention particulière...reste à prendre en compte les suppressions. J'ai pensé faire le symétrique (décrémenter nbInstance à chaque appel à un 'destructeur'), seulement y-a-t-il des destructeurs en Java ? Je me suis rapidement rendu compte que "finalize" n'en était pas un (au sens C++ du terme). Comment faire donc ?

    Merci pour votre aide !

  2. #2
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 559
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 559
    Points : 21 621
    Points
    21 621
    Par défaut
    Citation Envoyé par zlaptop Voir le message
    J'ai pensé faire le symétrique (décrémenter nbInstance à chaque appel à un 'destructeur'), seulement y-a-t-il des destructeurs en Java ? Je me suis rapidement rendu compte que "finalize" n'en était pas un (au sens C++ du terme). Comment faire donc ?
    En effet finalize() n'est pas un destructeur et il n'y a pas de destructeur en Java.

    Ce n'est pas vraiment possible de faire quelque chose de ce genre en Java. À la place, il te faudrait :

    - Soit un autre mécanisme d'enregistrement/déregistrement d'instances, à la création et appelé chaque fois que ton code décide "cette instance-là, on s'en servira plus"
    - Soit en faisant avec finalize() quand même, en sachant que même après l'appel à finalize(), l'instance peut quand même être là quelque part pendant un temps arbitrairement long.
    - Soit avec des outils de profiling spécialisés pour mesurer ce qui t'intéresse vraiment, ce qui, je suppose, n'est pas le nombre d'instances en cours de telle ou telle classe, mais le temps passé dans tel bout de code ou l'utilisation mémoire causée par quoi.

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 807
    Points
    48 807
    Par défaut
    pourquoi finalize ne te conviens pas?

  4. #4
    Rédacteur
    Avatar de CyberChouan
    Homme Profil pro
    Directeur technique
    Inscrit en
    Janvier 2007
    Messages
    2 752
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Directeur technique
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 752
    Points : 4 314
    Points
    4 314
    Par défaut
    Citation Envoyé par thelvin Voir le message
    En effet finalize() n'est pas un destructeur et il n'y a pas de destructeur en Java.
    finalize() n'est pas un destructeur, mais c'est une méthode qui est automatiquement appelée lorsque ta JVM décide de détruire l'objet.

    Tu ne dois pas l'appeler explicitement (cela fausserait ton comptage car ça n'assurerait pas la destruction de l'instance), mais tu peux t'en servir.

    Par exemple :

    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
    39
    public class TestComptage {
     
        private static int nbInstance = 0;
     
        private static final Object lock = new Object();
     
        public TestComptage() {
            synchronized(lock) {
                nbInstance++;
            }
        }
     
        public void finalize() {
            synchronized(lock) {
                nbInstance--;
            }
        }
     
        public static void main(String[] args) {
            TestComptage tc1 = new TestComptage();
            TestComptage tc2 = new TestComptage();
            TestComptage tc3 = new TestComptage();
     
            System.out.println(TestComptage.nbInstance);
     
            tc2 = null; // un objet n'est plus référencé et pourra être détruit
            tc3 = tc1; // un autre objet n'est plus référencé et pourra être détruit
     
            System.gc();
     
            try {
                // Pour laisser au GC le temps d'être effectivement exécuté
                Thread.sleep(3000);
            } catch (InterruptedException ie) {
            }
     
            System.out.println(TestComptage.nbInstance);
        }
    }
    A la construction d'un objet, le compteur d'instances est incrémenté.
    Quand la JVM décide de détruire l'objet, elle appelle finalize() avant ce qui assure normalement la décrémentation du compteur.

    Maintenant, si tu veux "forcer" la JVM a détruire les instances qui ne sont plus référencées, tu peux tenter d'invoquer explicitement le "garbage collector" par "System.gc();".

    Attention :
    - cette commande n'assure pas que le GC sera lancé immédiatement
    - elle n'assure pas non plus que les objets seront réellement détruits
    - lancer manuellement le GC est généralement une mauvaise pratique qui n'est utilisée qu'à des fins de test !!!

  5. #5
    Candidat au Club
    Inscrit en
    Juillet 2010
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Juillet 2010
    Messages : 4
    Points : 3
    Points
    3
    Par défaut
    Merci pour vos réponses. Effectivement finalize() n'est pas adaptée puisque ça ne maintiendra pas exactement le compteur à jour.

    Finalement si je comprend bien il n'y a donc pas vraiment d'autre façon que de faire ça "à la main"...


    - Soit avec des outils de profiling spécialisés pour mesurer ce qui t'intéresse vraiment, ce qui, je suppose, n'est pas le nombre d'instances en cours de telle ou telle classe, mais le temps passé dans tel bout de code ou l'utilisation mémoire causée par quoi.
    À vrai dire il s'agissait plus d'une question théorique que je me posais, sans application réelle.

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 807
    Points
    48 807
    Par défaut
    Citation Envoyé par zlaptop Voir le message
    sans application réelle.
    on est d'accord là dessus

  7. #7
    Membre chevronné
    Avatar de professeur shadoko
    Homme Profil pro
    retraité nostalgique Java SE
    Inscrit en
    Juillet 2006
    Messages
    1 257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 75
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : retraité nostalgique Java SE

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 257
    Points : 1 855
    Points
    1 855
    Par défaut
    Citation Envoyé par zlaptop Voir le message
    À vrai dire il s'agissait plus d'une question théorique que je me posais, sans application réelle.
    bien que ça soit un peu lourd pour ton besoin ça c'est du ressort des références faibles et des queues de références ... (mais bon c'est une question théorique hein!). remarque: à la fin il peut rester des objets non récupérés par le GC mais bon on n'a plus besoin du compte dans ce cas.

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    476
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 476
    Points : 595
    Points
    595
    Par défaut
    Finalement si je comprend bien il n'y a donc pas vraiment d'autre façon que de faire ça "à la main".
    Avec le langage Java pure, oui et sans aucune garantie.

    Maintenant, certaines apis tierces te permettent de dépasser les limites du langage.
    Par exemple, si tes instances sont gérées (donc créer et supprimer) et utilisables depuis une couche de plus haut niveau comme la factory d'objets du framework Spring, tu peux arriver sans mal à tes fins avec les listeners prévues.

  9. #9
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    155
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 155
    Points : 199
    Points
    199
    Par défaut
    Citation Envoyé par CyberChouan Voir le message
    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
    39
    public class TestComptage {
     
        private static int nbInstance = 0;
     
        private static final Object lock = new Object();
     
        public TestComptage() {
            synchronized(lock) {
                nbInstance++;
            }
        }
     
        public void finalize() {
            synchronized(lock) {
                nbInstance--;
            }
        }
     
        public static void main(String[] args) {
            TestComptage tc1 = new TestComptage();
            TestComptage tc2 = new TestComptage();
            TestComptage tc3 = new TestComptage();
     
            System.out.println(TestComptage.nbInstance);
     
            tc2 = null; // un objet n'est plus référencé et pourra être détruit
            tc3 = tc1; // un autre objet n'est plus référencé et pourra être détruit
     
            System.gc();
     
            try {
                // Pour laisser au GC le temps d'être effectivement exécuté
                Thread.sleep(3000);
            } catch (InterruptedException ie) {
            }
     
            System.out.println(TestComptage.nbInstance);
        }
    }
    Autant mettre des opérations atomique, c'est plus rapide.
    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
    public class TestComptage {
     
        private static AtomicInteger nbInstance = new AtomicInteger(0);
     
        private static final Object lock = new Object();
     
        public TestComptage() {
                nbInstance.increment();
        }
     
        public void finalize() {
                nbInstance.decrement();
        }
     
    }

Discussions similaires

  1. Réponses: 32
    Dernier message: 30/07/2009, 10h47
  2. [JMF] faire une action à chaque nouvelle frame de la webcam
    Par AlKoLiK dans le forum Multimédia
    Réponses: 0
    Dernier message: 11/02/2009, 03h23
  3. Effectuer une action à chaque clique
    Par supertoms dans le forum VBA Access
    Réponses: 6
    Dernier message: 15/05/2008, 08h36
  4. Réponses: 7
    Dernier message: 31/01/2007, 11h31
  5. Réponses: 10
    Dernier message: 17/05/2006, 19h55

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