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

Java Discussion :

Libérer la mémoire non utilisée


Sujet :

Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Développeur Java/GWT
    Inscrit en
    Juillet 2008
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur Java/GWT
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2008
    Messages : 32
    Par défaut Libérer la mémoire non utilisée
    Salut

    je suis en train de faire un programme qui contient un JTextPane et un un vecteur de JLabel. À chaque fois que le nombre de lignes dans le JTextPane change, j'ajoute un nouveau JLabel dans le vecteur qui correspond au numéro de la nouvelle ligne ou je supprime le JLabel qui correspond à la ligne supprimée.

    Le problème est que, lorsque je supprime un JLabel, l'espace qui utilise n'est pas libérée et je ne comprends pas pourquoi puisque normalement, c'est le gc qui s'en occupe lorsqu'il n'y a plus de référence à l'objet.

    Voici ma fonction setLinesNumber qui se charge de modifier les numéro de lignes.

    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
    private void setLinesNumber(int newLinesNumber){
    	//Calcule la taille minimum du nombre pour combler le reste avec des zéros
    	int newNumberLength = ("" + newLinesNumber).length(); 
    	if(newNumberLength < 2){
    		newNumberLength = 2;
    	}
    	int oldNumberLength = ("" + m_lblLinesNumberList.size()).length();
    	if(oldNumberLength < 2){
    		oldNumberLength = 2;
    	}
     
    	//Ajoute les zéro au label de l'ordre de grandeur précédante lors du changement d'ordre de grandeur
    	if(newNumberLength != oldNumberLength){
    		for(int i = 0; i < m_lblLinesNumberList.size(); i++){
    			m_lblLinesNumberList.get(i).setText("0" + m_lblLinesNumberList.get(i).getText());
    		}
    	}
     
    	//Ajoute le numéro de chaque nouvelle ligne
    	if(newLinesNumber > m_lblLinesNumberList.size()){
    		for(int i = m_lblLinesNumberList.size(); i < newLinesNumber; i++){
    			String numberToAdd = "";
    			for(int j = 0; j < newNumberLength - ("" + (i + 1)).length(); j++){
    				numberToAdd += "0";
    			}
    			numberToAdd += i + 1;
     
    			JLabel lblTemp = new JLabel(numberToAdd);
    			lblTemp.setForeground(Color.WHITE);
    			m_lblLinesNumberList.add(lblTemp);
    			m_pnlLinesNumber.add(m_lblLinesNumberList.get(m_lblLinesNumberList.size() - 1));
    		}
    	}
    	//Enlève le numéro de chaque ligne supprimée
    	else if(newLinesNumber < m_lblLinesNumberList.size()){
    		for(int i = m_lblLinesNumberList.size(); i > newLinesNumber; i--){
    			m_pnlLinesNumber.remove(m_lblLinesNumberList.get(i - 1));
    			m_pnlLinesNumber.updateUI();
    			m_lblLinesNumberList.remove(i - 1);
    		}
    	}
    }

  2. #2
    Membre expérimenté Avatar de hydraland
    Profil pro
    Développeur Java
    Inscrit en
    Mai 2006
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Mai 2006
    Messages : 179
    Par défaut
    Salut,

    Sur quoi te base tu pour dire que la mémoire n'est pas libéré?

    A+
    Hydraland

  3. #3
    Expert éminent
    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
    Billets dans le blog
    1
    Par défaut
    Salut,

    Citation Envoyé par Iron Bull Voir le message
    je suis en train de faire un programme qui contient un JTextPane et un un vecteur de JLabel. À chaque fois que le nombre de lignes dans le JTextPane change, j'ajoute un nouveau JLabel dans le vecteur qui correspond au numéro de la nouvelle ligne ou je supprime le JLabel qui correspond à la ligne supprimée.
    Quel est l'objectif de tout cela ?


    Citation Envoyé par Iron Bull Voir le message
    Le problème est que, lorsque je supprime un JLabel, l'espace qui utilise n'est pas libérée et je ne comprends pas pourquoi puisque normalement, c'est le gc qui s'en occupe lorsqu'il n'y a plus de référence à l'objet.
    Qu'est-ce qui te fait dire que les JLabels ne sont jamais libéré ?

    a++

  4. #4
    Expert éminent
    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 : 46
    Localisation : Belgique

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    n'oublie pas de retirer te JLable aussi de son conteneur graphique si tu ne veux plus le voir.

  5. #5
    Membre averti
    Homme Profil pro
    Développeur Java/GWT
    Inscrit en
    Juillet 2008
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur Java/GWT
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2008
    Messages : 32
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    Quel est l'objectif de tout cela ?
    Vous connaissez notepad++? Je veux simplement afficher le numéro de chaque ligne devant celle-ci.

    Citation Envoyé par adiGuba Voir le message
    Qu'est-ce qui te fait dire que les JLabels ne sont jamais libéré ?
    Dans le gestionnaire des tâches, lorsque je supprime les lignes, il n'y a aucune diminution de la mémoire utilisé par mon application. J'en déduis donc que la mémoire n'est pas libérée. Bien que se soit négligable pour quelques lignes, lorsqu'il sagit de plusieurs centaines de lignes, sa pose problème.

    Citation Envoyé par tchize_ Voir le message
    n'oublie pas de retirer te JLable aussi de son conteneur graphique si tu ne veux plus le voir.
    Mon conteneur graphique est un JPanel et je retire en effet le JLabel du JPanel lorsque je supprime une ligne.

    (Ce code est déjà écrit plus haut)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    //Enlève le numéro de chaque ligne supprimée
    	else if(newLinesNumber < m_lblLinesNumberList.size()){
    		for(int i = m_lblLinesNumberList.size(); i > newLinesNumber; i--){
    			m_pnlLinesNumber.remove(m_lblLinesNumberList.get(i - 1));
    			m_pnlLinesNumber.updateUI();
    			m_lblLinesNumberList.remove(i - 1);
    		}
    	}
    Sinon, est-ce qu'il y aurait un meilleur moyen que d'utiliser un JLabel pour chaque ligne?
    J'ai déjà essayé d'utiliser un JLabel unique, où chaque ligne est séparé par un <BR>, mais cela cause beaucoup de ralentissement dès qu'on dépasse 500 lignes (le texte du JLabel doit être réécrit à chaque fois).

  6. #6
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Iron Bull Voir le message
    Dans le gestionnaire des tâches, lorsque je supprime les lignes, il n'y a aucune diminution de la mémoire utilisé par mon application. J'en déduis donc que la mémoire n'est pas libérée. Bien que se soit négligable pour quelques lignes, lorsqu'il sagit de plusieurs centaines de lignes, sa pose problème.

    La machine virtuelle réserve de la mémoire à l'avance mais rien ne te dit qu'elle est utilisée. Pour le savoir, utilise un outil tel que jvisualvm qui est incluet par défaut dans le JDK de Sun depuis la version 1.6_10. Là tu verras si tu as de réeles problèmes de mémoire.

    A plus

  7. #7
    Membre averti
    Homme Profil pro
    Développeur Java/GWT
    Inscrit en
    Juillet 2008
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur Java/GWT
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2008
    Messages : 32
    Par défaut
    Citation Envoyé par George7 Voir le message
    La machine virtuelle réserve de la mémoire à l'avance mais rien ne te dit qu'elle est utilisée. Pour le savoir, utilise un outil tel que jvisualvm qui est incluet par défaut dans le JDK de Sun depuis la version 1.6_10. Là tu verras si tu as de réeles problèmes de mémoire.

    A plus
    Merci, je vais regarder ça chez moi ce soir.

    Donc si c'est le cas, lorsque je supprime les JLabel associés aux lignes supprimées, la jvm réserve de la mémoire. Mais lorsque je recrée les JLabel lors d'ajout de nouvelles lignes, pourquoi est-ce que la jvm n'utilise pas cette mémoire "réservé" au lieu de prendre encore plus de place en mémoire?
    Comment faire pour libérer complètement la mémoire qu'il réserve puisqu'il ne semble pas s'en servir?

  8. #8
    Expert éminent
    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 : 46
    Localisation : Belgique

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    C'est pas aussi simpel que ca. Le modèle de mémoire de la jvm fait qu'il n'y a pas de lien direct entre la mémoire système et la mémoire java. D'abord, quand tun objet n'est plus référencé, il est ramassable par le ramasse miettes, mais il ne va pas l'etre immédiatement. Cette analyse est assez couteuse et donc on limite autant que possible les nettoyages. C'est donc plus proche du gros nettoyage de printemps que du coup de balais vite fait. Par contre, un garantie il me semble de la jvm, c'est que le nettoyage va être fait en priorité avant d'augmenter la taille de la jvm. Si la mémoire continue d'augmenter, c'est que tu n'a pas supprimé toutes les références à ton JLabel (ou à d'autres objets, rien ne dit que le JLabel est en cause).

    Si t'as un doute, crée tes JLabel comme çà:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    new JLabel("texte"){
      protected void finalize() throws Throwable{
        System.out.println("nettoyage de "+getText());
      }
    }

  9. #9
    Membre éclairé
    Inscrit en
    Juin 2006
    Messages
    570
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 570
    Par défaut
    Le GC ne passe pas dés qu'un objet n'est plus utilisé, mais selon d'autre alogrithm.

    De plus, c'est pas forcément simple à voir sur le gestionnaire de tache, tu ne sais pas si la mémoire n'est pas alloué pour d'autre chose.
    Si tu veux etre sur qu'ils sont bien pris par le gc, tu créé ton propre JLabel dans le quel tu met une variable static "compteur". Dans le constructeur de ton composant, tu incrémentes compteur. Tu overwrite ensuite la méthode finalize(), dans la quelle tu décrémentes compteur.

    Tu regardes si ta variable compteur ne fait qu'augmenter au cours du temps, c'est que tes composants ne sont jamais détruits.

Discussions similaires

  1. Libérer rapidement un objet utilisant bcp de mémoire vive
    Par ZebreLoup dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 29/03/2010, 14h46
  2. [dll] libérer une dll apres utilisation
    Par polo54 dans le forum API standards et tierces
    Réponses: 12
    Dernier message: 11/07/2009, 22h48
  3. Libérer la mémoire aprés utilisation de collection
    Par harris_macken dans le forum Collection et Stream
    Réponses: 7
    Dernier message: 27/03/2008, 00h01
  4. Fuite de mémoire en utilisant le template list
    Par schtroumpf_farceur dans le forum Langage
    Réponses: 9
    Dernier message: 18/07/2005, 20h44
  5. Réponses: 1
    Dernier message: 28/04/2004, 19h36

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