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

Composants Java Discussion :

composants et libération de mémoire


Sujet :

Composants Java

  1. #1
    Membre habitué

    Homme Profil pro
    Enseignant
    Inscrit en
    Février 2020
    Messages
    167
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Février 2020
    Messages : 167
    Points : 162
    Points
    162
    Par défaut composants et libération de mémoire
    bonjour à tous,

    je travaille sur un logiciel qui positionne des composants graphiques swing, sur d'autres composants graphiques swing.

    En fait, quand je veux effacer un composant graphique que j'ai créé, et ne plus occuper son espace mémoire, j'écris :
    composant1 = null.
    Ainsi je pense ne plus le référencer et donc, quand je repaint le conteneur, ce dernier n'apparait plus et son espace mémoire n'est plus occupé.
    1/ Ma pratique est-elle la bonne?

    Ensuite, quand j'ai un conteneur qui contient beaucoup de composants graphiques swing, et que je veux tout effacer, j'écris :
    conteneur1 = null.
    En fait je procède de la même manière.
    Mon objet conteneur1 n'étant plus référencé, si je repeint la fenêtre principal, il disparaît, avec tous mes composants graphiques qui lui appartenaient.
    2/ Cependant, Je n'ai pas mis à la valeur "null", tous les composants qui étaient sur ce conteneur, de manière individuelle, que sont-ils devenus??
    Sont-ils spontanément déréférencés quand leur conteneur support a été lui-même déréférencé, ou existe-t-il toujours en mémoire, ce qui me générait un peu car je passe mon temps à changer de conteneur support pour lui ajouter mes composants graphiques, puis les détruire sans arrêt....

    En espérant m'être fait comprendre... merci.

  2. #2
    Membre régulier

    Inscrit en
    Novembre 2010
    Messages
    44
    Détails du profil
    Informations forums :
    Inscription : Novembre 2010
    Messages : 44
    Points : 124
    Points
    124
    Par défaut
    Bonjour,

    Je n'ai pas compris. Il faudrait fournir un code source qui illustre le procédé.
    En mettant un composant à null, tu perds la référence, mais cela ne veut pas dire que Swing lui aussi perds la référence. A partir du moment où le composant est ajouté à la fenêtre, il sera référencé par la fenêtre et ne sera donc pas libéré.
    Il faut utiliser la méthode remove pour retirer le composant, et ensuite faire les revalidate/repaint (je ne suis pas sur de l'appel exact, mais moi je fait revalidade + repaint et cela fonctionne).

    Voici mon code d'exemple avec un bouton qui efface un Label.
    Le premier bouton ne fait rien, d'apparent puisqu'il met à null le label.
    Le second bouton retire le label par la méthode remove : Il fonctionne.
    Si on utilise le second bouton après le premier, on a une erreur puisque la variable composantAEffacer est mis à null.

    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
     
    public class TestEffaceComposant {
    	static JLabel composantAEffacer;
    	static JPanel jpanel;
     
    	public static void main(String[] args) {
    		JFrame fen = new JFrame();
    		fen.setVisible(true);
    		fen.setSize(1000, 800);
    		fen.setLocationRelativeTo(null);
    		jpanel = new JPanel();
    		fen.setContentPane(jpanel);
     
    		composantAEffacer = new JLabel("Texte à effacer");
    		jpanel.add(composantAEffacer);
     
    		JButton boutonNull = new JButton("Effacement par null");		
    		jpanel.add(boutonNull);
    		boutonNull.addActionListener(e -> {
    			composantAEffacer = null;
    			fen.revalidate();
    			fen.repaint();						
    		});
    		JButton boutonRemove = new JButton("Effacement par remove");
    		jpanel.add(boutonRemove);
    		boutonRemove.addActionListener(e -> {
    			jpanel.remove(composantAEffacer);
    			fen.revalidate();
    			fen.repaint();			
    		});
     
    	}
    }

  3. #3
    Membre habitué

    Homme Profil pro
    Enseignant
    Inscrit en
    Février 2020
    Messages
    167
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Février 2020
    Messages : 167
    Points : 162
    Points
    162
    Par défaut merci seroze
    bonjour seroze,

    1/
    en fait je souhaite une confirmation déja sur ces deux commandes :
    "remove" : retire de l'affichage un objet, mais qui existe toujours, et donc, peut être rappelé, ré-affiché et manipulé à loisir.
    "=null" : entraîne la perte de la référence en mémoire de cet objet, et donc, ce dernier est définitivement perdu car le lien d’accès et brisé. C'est cela qui d'ailleurs permet au "garbade collector", de tourner dans la mémoire, de repérer les objets qui, n'étant plus référencés, sont perdus à jamais, et donc, de permettre à nouveau l'utilisation de l'espace mémoire qu'il occupaient.
    Suis-je dans le vrai??

    2/ Si je mets un objet à la valeur "null", son espace mémoire sera donc libéré de manière automatique, sans que j'ai une autre démarche à faire?

    3/ Si je mets mon JPanel à la valeur "null", l'espace mémoire de cet objet sera normalement libéré. Mais s'il contenait 200 composants redéfinis SWING, sont-ils automatiquement supprimés également, ou existent-ils toujours pour rien? Le garbade collector sait-il s'en rendre compte et supprimer tous les enfants de ce JPanel pour libérer tous ces espaces mémoires??

    Merci....

  4. #4
    Membre régulier

    Inscrit en
    Novembre 2010
    Messages
    44
    Détails du profil
    Informations forums :
    Inscription : Novembre 2010
    Messages : 44
    Points : 124
    Points
    124
    Par défaut
    J'en appelle à des plus savants que moi, car le garbage collector n'est pas simple et de plus, il a évolué au fil des version de Java.

    Ce qui est sur, c'est que affecter un objet à null ne va pas immédiatement libérer la mémoire. La mémoire sera éventuellement libérée lorsque toutes les références de l'objet seront mise à null ou affectés à un autre objet.

    Si tu ajoutes le Jpanel à la fenêtre et ensuite que la variable est mise à null, l'objet JPanel continue à être référencé par la fenêtre, donc il ne dois pas être libéré.

    Voici un exemple de code où je créé une liste, je garde une copie de sa référence. Quand je met à null ma variable qui a servi à la création de la liste, la copie continue à référencer la liste. La liste est donc toujours présente en mémoire.

    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
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
     
    public class testListe {
     
    	private int valeur;
    	private testListe suivant = null;
     
    	public testListe(int valeur) {
    		super();
    		this.valeur = valeur;
    	}
     
    	public void Ajout(int valeur) {
    		if (suivant == null) {
    			suivant = new testListe(valeur);
    		} else {
    			suivant.Ajout(valeur);
    		}
    	}
     
    	public void lister() {
    		System.out.print(valeur + " ");
    		if (suivant != null)
    			suivant.lister();
    	}
     
    	public static void main(String[] args) {
    		testListe liste1 = new testListe(1);
    		liste1.Ajout(2);
    		liste1.Ajout(3);
    		testListe liste2 = liste1;
    		System.out.println("Contenu de liste 1");
    		liste1.lister();
    		System.out.println();
    		System.out.println("Contenu de liste 2");
    		liste2.lister();
    		liste1 = null;
    		System.out.println();
    		System.out.println("Contenu de liste 2 après mise à null de liste 1");
    		liste2.lister();
    		System.out.println();
    		System.out.println("Contenu de liste 1 après mise à null de liste 1");
    		try {
    			liste1.lister();
    		} catch (Exception e) {
    			System.out.println("Erreur sur appel de liste1.lister !");
    		}
    		liste2 = null;
    		System.out.println("Les deux références sont nulles, la mémoire qui état utilisée par la liste devrait être collectable");
    	}
    }
    J'espère que le garbage collector fonctionne bien et que à l'issue du programme, puisque je met à null toutes mes références, chaque élément de la liste sera libéré (y compris l'élément 2 et 3)
    Je ne sais pas comment le garbage collector travaille. Le dernier élément de la liste reste référencé par le précédent, mais comme il n'y a plus de référence à la tête de liste, le garbage collector devrait s'en rendre compte et tout libérer. J'imagine que le code du garbage collector et son comportement est complexe.

    Donc logiquement, si tu retires de la fenêtre ton panel contenant des objets et que tu mes à null la référence du panel (ou que la variable contenant le panel n'est plus accessible) et que plus rien ne référence les objets contenus dans le panel, alors le garbage collector devrais être capable de récupérer la mémoire à un moment donné.

  5. #5
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Pour résumer :

    - oui, le garbage collector sait détecter quand un objet n'est plus référencé que par des objets qui ne sont plus accessibles, et donc qu'ils peuvent tous être collectés. Cela inclut les références circulaires.

    - Le garbage collector ne s'applique pas dès qu'il le peut. En fait, rien ne garantit qu'un objet sera collecté, on sait seulement quand il pourrait l'être si besoin. Un objet encore accessible par d'autres, ne sera jamais collecté. Un objet qui n'est plus référencé, peut être collecté.

    Supposons qu'on ait pas besoin de la mémoire occupée par cet objet, dans ce cas il n'y a aucun intérêt à perdre du temps à gérer la libération de sa mémoire. Il existe de nombreux algorithmes de garbage collectors et ils ne prennent pas tous les mêmes décisions, mais en résumé Java cherche à ne libérer la mémoire, que quand c'est bénéfique de le faire. Et on peut pas trop prédire qu'est-ce qui peut faire qu'il soit bénéfique de libérer la mémoire d'un objet précis, surtout s'il n'en occupe pas beaucoup, de mémoire. A la rigueur, quand un programme commence à manquer de mémoire, Java commencera par collecter tout ce qu'il peut avant de déclencher une erreur de manque de mémoire. Du coup, il peut arriver que cela n'arrive jamais, et que la mémoire ne soit libérée que par l'arrêt du programme lui-même par l'OS, et pas par Java.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  6. #6
    Membre habitué

    Homme Profil pro
    Enseignant
    Inscrit en
    Février 2020
    Messages
    167
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Février 2020
    Messages : 167
    Points : 162
    Points
    162
    Par défaut merci.
    Bonsoir Seroze et Thelvin, merci à tous les deux pour vos explications.

    Le fonctionnement de fond du garbage collector reste un peu opaque pour moi, qui ne connait pas toute la mécanique de traitement sous de capot logiciel, mais grâce à vous j'appréhende mieux la démarche de suppression d'objets sur mes interfaces graphiques. Encore merci car quand on est dans sa bulle, ca aide à prendre du recul, et à bientôt certainement pour d'autres questionnements...

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

Discussions similaires

  1. Libération de mémoire non réservée (operator=)
    Par 84mickael dans le forum C++
    Réponses: 7
    Dernier message: 27/05/2006, 13h30
  2. Problème libération de mémoire?
    Par Bartuk dans le forum C
    Réponses: 7
    Dernier message: 28/12/2005, 17h20
  3. Libération de mémoire
    Par petitcoucou31 dans le forum Langage
    Réponses: 1
    Dernier message: 16/09/2005, 14h10
  4. [Debutant(e)]problème de libération de mémoire
    Par skywalker3 dans le forum Eclipse Java
    Réponses: 1
    Dernier message: 10/02/2005, 17h38
  5. Réponses: 25
    Dernier message: 16/07/2003, 20h41

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