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

Langage Java Discussion :

garbage collector et finalize() Comment les utiliser ?


Sujet :

Langage Java

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 27
    Points : 11
    Points
    11
    Par défaut garbage collector et finalize() Comment les utiliser ?
    Bonjour,

    voici mon programme :

    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
     
    public class Chien{
     
    	private String nom, aboiement;
    	private static int numero = 0 ;
    	private int numeroperso = 0 ;
     
    	public Chien(){
    	nom = "Toutou";
    	aboiement = "wouf";
    	numero++;
    	numeroperso = numero;
    	}
     
    	public Chien(String nom, String aboiement){
    	this.nom = nom;
    	this.aboiement = aboiement;
    	numero++;
    	numeroperso = numero;
    	}
     
    	public int getIdent(){
    	return numeroperso;
    	}
     
    	public int getIdentMax(){
    	return numero;
    	}
     
    	protected void finalize() throws Throwable{
    	if(this == null) // je ne suis pas sure du tout que ça doit commencer comme ca...
    	{}
    	}
    }
    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
     
    public class TestChien{
     
    	public static void main(String args[]){
     
    	Chien B = new Chien("Médor", "aaaa");
    	System.out.println(B.getIdent());
    	Chien C = new Chien("Bill", "waaaf");
    	Chien D = new Chien("Bill2", "waaaf2");
    	System.out.println(C.getIdent());
    	Chien A = new Chien();
    	System.out.println(A.getIdent());
    	System.out.println(B.getIdent());
    	System.out.println(C.getIdentMax());
    	A = B;
    	B = C;
    	D = null;
    	System.out.println(A.getIdent());
    	System.out.println(B.getIdent());
    	System.gc();	
    	System.out.println(A.getIdent());
    	System.out.println(B.getIdent());
    	System.out.println(D.getIdent());
    	}
    J'utilise System.gc() pour obliger le programme à lancer le garbage collector. Je voulais tout d'abord savoir si le garbage collector sert bien à supprimer les objets (ou à libérer la case mémoire : quelle est la différence ?) qui sont null.
    Quand je lance TestChien, il veut bien le compiler mais lors de l'exécution, il y a une erreur car c'est normal, D = null
    Si j'ai bien compris, ma méthode finalize() se lance toute seule (pas besoin de l'appeler dans main) mais je ne sais pas quoi écrire dedans : est-ce qu'elle est bien sensée supprimer les objets ? Est-ce la même chose que le garbage collector ou un outil du garbage collector ?

    Je dois aussi créer une variable et la/les méthode/s nécessaire/s pour savoir environ le nombre de chiens dans le programme.

    Est-ce que mon objet Chien D est bien candidat au ramasse miette ? Comment savoir qu'il a été ramassé ?
    Et aussi : à quoi sert protected ?

    J'ai bien regardé les tutoriels mais je ne trouve pas de détails sur l'utilisation du ramasse miette.

    Merci pour votre aide

  2. #2
    Expert éminent sénior
    Avatar de Baptiste Wicht
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2005
    Messages
    7 431
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2005
    Messages : 7 431
    Points : 21 324
    Points
    21 324
    Par défaut
    En fait, c'est assez simple, il n'y a pas besoin de redéfinir la méthode finalize() sauf peut-être dans certains cas. De plus, tu ne peux même pas garantir que cette méthode sera appellée une fois dans ton programme.

    D est bien candidat au ramasse-miettes en effet, mais rien ne dit quand le gc va s'en débarasser... De plus, il est aussi déconseillé d'utiliser System.gc(), car rien ne permet d'être sûr qu'il viendra tout de suite et ca risque de ralentir ton programme. Le mieux avec le gc c'est de le laisser fonctionner tout seul.

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 27
    Points : 11
    Points
    11
    Par défaut
    C'est un exercice de TP et on nous demande d'utiliser System.gc

  4. #4
    Membre confirmé Avatar de Satch
    Homme Profil pro
    Hypnothérapeute - Magicien
    Inscrit en
    Mars 2004
    Messages
    498
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Suisse

    Informations professionnelles :
    Activité : Hypnothérapeute - Magicien

    Informations forums :
    Inscription : Mars 2004
    Messages : 498
    Points : 645
    Points
    645
    Par défaut
    Citation Envoyé par HighSchool2005
    C'est un exercice de TP et on nous demande d'utiliser System.gc
    Si ton prof insinue qu'en utilisant System.gc() ça fait passer le garbage collector qui va virer tous les objets qui ne sont plus référencés, tu peux lui dire qu'il ferait mieux re réviser un peu ses cours de java.
    Je sais que désormais vivre est un calembour,
    La mort est devenue un état permanent,
    Le monde est aux fantômes, aux hyènes et aux vautours.
    Moi je vous dis bravo et vive la mort.

  5. #5
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 274
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 274
    Points : 4 141
    Points
    4 141
    Par défaut
    Si ton prof insinue qu'en utilisant System.gc() ça fait passer le garbage collector qui va virer tous les objets qui ne sont plus référencés, tu peux lui dire qu'il ferait mieux re réviser un peu ses cours de java.
    Parce que c'est pas le cas ?
    System.gc() appelle le garbage collector, sauf qu'on ne peut pas savoir quand précisement.
    Non ?

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 27
    Points : 11
    Points
    11
    Par défaut
    C'est surement moi qui me suis mal exprimée ou qui est mal compris...

    Voici le sujet après avoir créé la classe Chien et une classe Test

    Malheureusement, il est possible que certains chiens disparaissent. (par exemple lorsque le ramasse miette détecte un chien qui n'est plus référencé) Compléter la classe précédente en ajoutant une variable permettant de savoir à peu près combien de chiens sont présents dans le programme. Ajouter la ou les méthodes nécessaires à ce comptage.
    Aide : déclaration de la méthode finalize() :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    protected void finalize() thows Throwable
    {
    ...
    }
    Pour tester votre code, il faudra faire en sorte que certains objets soient candidat au ramasse-miette. Il n'est pas possible de contrôler le lancement du garbage collector (à vous de trouver comment) mais on peut indiquer à la JVM que l'on souhaite appeler le ramasse-miette ce qui se fait par l'instruction System.gc
    Il dit bien qu'on ne peut pas controler le lancement du ramasse miette mais on peut l'appeler. (Quelle est la différence d'ailleurs entre l'appeler et le lancer ?)
    Le "(à vous de trouver comment)" n'a pas beaucoup de sens pour moi.
    J'espère que des personnes plus expérimentées que moi en java pourront m'aider.

  7. #7
    Membre chevronné
    Profil pro
    Fabrication GED
    Inscrit en
    Octobre 2005
    Messages
    1 405
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Fabrication GED

    Informations forums :
    Inscription : Octobre 2005
    Messages : 1 405
    Points : 1 958
    Points
    1 958
    Par défaut
    on va faire une analogie :
    prend un ballon, lance dans un arbre de manière qu'il se coince. Hurle très fort en espérant que les vibrations le feront descendre ( "l'appel à la méthode" dans ton cas ), cependant s'il doit réellement descendre, ce seront les lois de la physique qui le feront ( "le lancement de la méthode par la JVM" dans ton cas ).

  8. #8
    Rédacteur
    Avatar de benwit
    Profil pro
    dev
    Inscrit en
    Septembre 2004
    Messages
    1 676
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : dev

    Informations forums :
    Inscription : Septembre 2004
    Messages : 1 676
    Points : 4 265
    Points
    4 265
    Par défaut
    Tout ce qui a été dit par les autres est vrai mais en survolant rapidement la discussion, je pense avoir compris l'interêt de l'exercice.

    Par contre, j'ai un petit doute sur un point ? (Merci aux autres de me confirmer s'ils en sont certains) Lorsqu'on dit que la méthode finalize n'est pas sûr d'être appelée, est-ce parce ce qu'on n'est pas sûr de l'appel du GC ou est-ce pour une autre raison ? Autrement dit, est que le déclenchement du GC (peu importe quand il intervient du moment où il intervient) déclenche systématiquement la méthode finalize d'un objet ?

    Ceci étant supposé, on pourrait imaginer que l'interêt de l'exercice serait de comprendre la différence entre variable d'instance et variable de classe (static) et donc que décrémenter le nombre total de chien dans finalize aurait un sens, numero représentant alors le nombre total de chien se promenant dans la mémoire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    protected void finalize() thows Throwable
    {
            numero-- ;
    }

    Tout le monde savait que c'était impossible. Il est venu un imbécile qui ne le savait pas et qui l'a fait. Marcel PAGNOL
    On ne savait pas que c'était impossible, alors on l'a fait. John Fitzgerald KENNEDY.
    L'inexpérience est ce qui permet à la jeunesse d'accomplir ce que la vieillesse sait impossible. Paul (Tristant) BERNARD
    La meilleure façon de prédire l'avenir, c'est de l'inventer.

  9. #9
    Membre chevronné
    Profil pro
    Fabrication GED
    Inscrit en
    Octobre 2005
    Messages
    1 405
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Fabrication GED

    Informations forums :
    Inscription : Octobre 2005
    Messages : 1 405
    Points : 1 958
    Points
    1 958
    Par défaut
    Tu m'as l'air d'avoir tout compris à une exception près : la méthode finalize est FORCEMENT appelée par le gc lorsqu'il se met en marche alors que le System.gc n'est lui pas forcément exécuté.

  10. #10
    Rédacteur
    Avatar de benwit
    Profil pro
    dev
    Inscrit en
    Septembre 2004
    Messages
    1 676
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : dev

    Informations forums :
    Inscription : Septembre 2004
    Messages : 1 676
    Points : 4 265
    Points
    4 265
    Par défaut
    iohack, pourquoi tu dis "à une exception près" supposant par là que je n'ai pas compris le fonctionnement du GC.

    Pour moi, il est évident que la méthode finalize est appelée par le GC lorsqu'il se met en marche de même que le System.gc n'est lui pas forcément exécuté.

    J'ai bien dit "petit doute" car je me demande s'il n'y aurait pas des cas particuliers ?
    Exemple, suppossons que le GC s'execute, appel une méthode finalize d'un objet et qu'une exception se produise ? Est-ce que le GC s'arrête ? continue ? Cela dépend t'il de l'implémentation du GC ? C'est tout ce que mon incertitude signifie !

    Tout le monde savait que c'était impossible. Il est venu un imbécile qui ne le savait pas et qui l'a fait. Marcel PAGNOL
    On ne savait pas que c'était impossible, alors on l'a fait. John Fitzgerald KENNEDY.
    L'inexpérience est ce qui permet à la jeunesse d'accomplir ce que la vieillesse sait impossible. Paul (Tristant) BERNARD
    La meilleure façon de prédire l'avenir, c'est de l'inventer.

  11. #11
    Membre chevronné
    Profil pro
    Fabrication GED
    Inscrit en
    Octobre 2005
    Messages
    1 405
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Fabrication GED

    Informations forums :
    Inscription : Octobre 2005
    Messages : 1 405
    Points : 1 958
    Points
    1 958
    Par défaut
    on pinaille là
    finalize est forcément appelée par gc().
    cependant gc() n'est pas forcément exécuté malgré l'appel.
    on peut en conclure que finalize n'est pas forcément appelée puisque gc est dans le même cas..

  12. #12
    Inactif  
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    2 189
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2006
    Messages : 2 189
    Points : 2 336
    Points
    2 336
    Par défaut
    Je me pose la question si l'on force l appelle de gc que se passe t il (si une class n implémente pas finalize)

    Es ce qu il existe (surment mais bon) une méthode hériter d une classe *systeme* ou autre qui définit la suppression d'un objet ?

  13. #13
    Membre chevronné
    Profil pro
    Fabrication GED
    Inscrit en
    Octobre 2005
    Messages
    1 405
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Fabrication GED

    Informations forums :
    Inscription : Octobre 2005
    Messages : 1 405
    Points : 1 958
    Points
    1 958
    Par défaut
    Il ne se passe rien si une classe ne surcharge pas finalize, le(s) handleurs sont détruits et leur mémoire d'adresse libérée, puis l'occupation mémoire des attributs/pointeurs est elle aussi libérée.

  14. #14
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,


    Citation Envoyé par benwit
    Exemple, suppossons que le GC s'execute, appel une méthode finalize d'un objet et qu'une exception se produise ? Est-ce que le GC s'arrête ? continue ? Cela dépend t'il de l'implémentation du GC ?
    Le traitement de la méthode finalize() s'interrompt, mais le GC continuera à s'exécuter normalement...

    Citation Envoyé par iohack
    finalize est forcément appelée par gc().
    finalize() est forcément appelée (et une seule fois) par le GC une fois que l'objet est candidat à la suppression, et avant qu'il ne soit réellement "supprimé". Par contre rien ne garantie que la méthode soit appelée pendant l'exécution du programme. Ainsi lorsque le programme se termine (fin normal, plantage ou System.exit()) la méthode finalize() n'est pas forcément appelée...



    Citation Envoyé par *alexandre*
    Je me pose la question si l'on force l appelle de gc que se passe t il (si une class n implémente pas finalize)
    Ben c'est tout simplement la méthode finalize() de la classe parente qui est appelé, en sachant que l'implémentation de cette méthode dans Object ne fait rien du tout...

    Citation Envoyé par *alexandre*
    Es ce qu il existe (surment mais bon) une méthode hériter d une classe *systeme* ou autre qui définit la suppression d'un objet ?
    On ne gère pas la suppression des objets en Java (contrairement au C++) : c'est le GC qui se charge de tout !
    La méthode finalize() peut être utilisé comme un garde-fou pour libérer les resources qui ne sont pas géré par le GC (fichiers, sockets, etc.)



    Nota : toutes ces infos sont indiqué dans la doc : http://javasearch.developpez.com/j2s...tml#finalize()

    a++

  15. #15
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 27
    Points : 11
    Points
    11
    Par défaut
    Ceci étant supposé, on pourrait imaginer que l'interêt de l'exercice serait de comprendre la différence entre variable d'instance et variable de classe (static) et donc que décrémenter le nombre total de chien dans finalize aurait un sens, numero représentant alors le nombre total de chien se promenant dans la mémoire


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    protected void finalize() thows Throwable { numero-- ; }
    J'ai mis le code proposé mais plusieurs questions restent sans réponse:
    -pourquoi numero ne vaut que 2 ? Je pensais que seul D était candidat au GC.

    -ce qui est étrange et que si j'ai bien compris, même avec System.gc cela ne garantit pas que finalize sera appelé : alors pourquoi numero vaut toujours 2 ?

    -si j'enlève System.gc et que j'exécute mon programme plusieurs fois, numero vaut toujours 4. Pourtant, je pensais que le gc pouvait se lancer tout seul donc parfois, il devrait appeler finalize et numero devrait diminuer, non ?

  16. #16
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par HighSchool2005
    -pourquoi numero ne vaut que 2 ? Je pensais que seul D était candidat au GC.
    Tu crées 4 instances de chiens :
    • "Médor", référencé par B
    • "Bill", référencé par C
    • "Bill2", référencé par D
    • et enfin un dernier chien "sans nom" référencé par A


    Mais lorsque tu joues avec les références :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    A = B;
    B = C;
    D = null;
    Tu perds bien 2 instances de chiens, puisque :
    • A référence désormais "Médor" au lieu de "sans nom".
      B référence désormais "Bill" au lieu de "Médor".
      C continue à référencer "Bill".
      D ne référence plus rien (null) et on perd donc "Bill2".

    Donc il te reste deux chiens référencés ("Médor" par A et "Bill" par B et C).

    Donc les chiens "sans nom" et "Bill2" sont donc candidat au GC...


    Citation Envoyé par HighSchool2005
    -ce qui est étrange et que si j'ai bien compris, même avec System.gc cela ne garantit pas que finalize sera appelé : alors pourquoi numero vaut toujours 2 ?
    System.gc ne garantie pas que le GC soit exécuté... et c'est tout !
    Mais la méthode finalize() est forcément appelé avant qu'un objet soit supprimé par le GC. Donc dans ton cas le GC est bien lancé à chaque fois, et il exécute donc les méthodes finalize() AVANT de supprimer les objets de la mémoire...

    Citation Envoyé par HighSchool2005
    -si j'enlève System.gc et que j'exécute mon programme plusieurs fois, numero vaut toujours 4. Pourtant, je pensais que le gc pouvait se lancer tout seul donc parfois, il devrait appeler finalize et numero devrait diminuer, non ?
    Parce que le GC gère la mémoire de manière intelligente. Il ne supprime pas forcément les objets immédiatement dès qu'il sont candidat à la suppression...
    En fait il gère plusieurs collections d'objets et vérifie de temps en temps s'il doit les supprimer ou pas.

    Mais il y a un cas particulier : une fois que l'application est terminée il efface tout d'un coup (sans appeler toutes les méthodes finalize()).

    Donc lorsque tu n'appelles pas explicitement le GC, et puisque tu n'utilises que très peu d'objet (et donc peu de mémoire), le GC n'a pas besoin de faire le ménage et donc les objets ne sont pas supprimé pendant l'exécution de ton programme...


    pour plus d'info sur le GC : http://gfx.developpez.com/tutoriel/java/gc/

    a++

  17. #17
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 27
    Points : 11
    Points
    11
    Par défaut
    merci c'est vraiment beaucoup plus clair maintenant.

  18. #18
    Membre confirmé
    Avatar de mhamedbj
    Profil pro
    Inscrit en
    Février 2007
    Messages
    403
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 403
    Points : 554
    Points
    554
    Par défaut une autre question.....
    si la méthode finalize() est forcément appelé avant qu'un objet soit supprimé par le GC mais que rien ne garantie que la méthode soit appelée pendant l'exécution du programme, lorsque le programme se termine (fin normal, plantage ou System.exit()) la méthode finalize() n'est pas forcément appelée...
    donc comment garentir un traitement avant la destruction d'un objet, je m'explique:
    mon but est de sauvegarder des données d'un objet dans un fichier Properties, ces données changent constamment au cours de l'exécution du programme, je voudrais donc garder une savegarde des attribus, avant la destruction de cet objet pour ensuite les relire lors de l'appel du constructeur... est-ce posible ????

    merci
    Si on tombe un jour... c'est pour mieux se relever !!
    Take a look

    Mon début de carrière

Discussions similaires

  1. Fuzznuc/TACG comment les utiliser?
    Par Mayeu dans le forum Bioinformatique
    Réponses: 6
    Dernier message: 01/11/2007, 16h36
  2. [VS.NET][Ressources]Comment les utiliser
    Par NicolasJolet dans le forum Visual Studio
    Réponses: 2
    Dernier message: 06/10/2006, 11h16
  3. Réponses: 1
    Dernier message: 13/12/2005, 17h48
  4. [Properties] comment les utiliser ?
    Par Kyti dans le forum Collection et Stream
    Réponses: 6
    Dernier message: 25/03/2005, 10h37
  5. Réponses: 7
    Dernier message: 13/03/2005, 16h45

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