Encore un problème de mémoire

Résolu
mdrcedrick Messages postés 54 Date d'inscription dimanche 12 septembre 2004 Statut Membre Dernière intervention 22 novembre 2007 - 9 juil. 2007 à 14:27
cs_GodConan Messages postés 2113 Date d'inscription samedi 8 novembre 2003 Statut Contributeur Dernière intervention 6 octobre 2012 - 10 juil. 2007 à 15:45
bonjour

sur mon application j'ouvre régulièrement des petites JFrame qui
contiennent des JLabel JTextField JButton, rien de bien complexe

par ailleur je lance en même temps une petite appli que j'ai trouvé et qui montre dans un graphique la consommation de mémoire

donc lorsque je lance une de ces petites JFrame ma conso mémoire
augmente c'est normal ... or lorsque je ferme la fenêtre je remet
toutes les déclarations à null et je lance le garbage collector
derrière et je fais un dispose() ensuite pour fermer cette fenetre.

cependant celà fait une demie-heure que je laisse tourner le graph pour
voir la diminution de la mémoire mais elle n'arrive pas !

est-ce que je fais quelque chose de la mauvaise manière afin de la libérer de la mémoire


car hier j'ai lancé 10 fenetres différentes et je suis vite arrivé à une pénurie de mémoire


merci d'avance pour vos conseils





don't cross the crocked step

15 réponses

cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
9 juil. 2007 à 21:35
ok, je croyais que si on forçais le GC, il faisait son boulot jusqu'au bout, mais c'est vrai que pour des raisons d'optimisations, cela peut se comprendre !
3
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
9 juil. 2007 à 14:44
Utilise tu une connection à une base de données ? Accède tu à des fichiers ? Ou utilise tu tout autres ressources qui nécessite d'être fermées à la main ?
0
mdrcedrick Messages postés 54 Date d'inscription dimanche 12 septembre 2004 Statut Membre Dernière intervention 22 novembre 2007
9 juil. 2007 à 14:52
oui tout à fait j'utilise un connexion à une base de données

et de la même manière que j'initialise cela :


Connection
            
connectMySQL        =    
    null;

Statement            
  ordreMySQL         
=         null;

ResultSet            
  resultat           
=         null;

ResultSetMetaData      
étaOrdre           
=         null;
et après avoir tout fait (et fermer la connexion) je fais :

connectMySQL       =         null;

ordreMySQL         =         null;

resultat           =         null;

métaOrdre          =         null;

System.gc();

mais rien n'y fait



don't cross the crocked step
0
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
9 juil. 2007 à 15:01
montre voir ton code de fermeture de tes resultset, de statement et de connection.

Sinon, essaye de voir avec un outil de profiling pour voir qu'est-ce qui te provoque cette fuite mémoire (mais à première vue, je dirais que ca vient de la base de données : faut être hyper rigoureux avec ces fichues bases!)
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
mdrcedrick Messages postés 54 Date d'inscription dimanche 12 septembre 2004 Statut Membre Dernière intervention 22 novembre 2007
9 juil. 2007 à 15:05
voila la méthode que j'utilise lors du lancement de ma JFrame pour remplir les champs

    private    
    void        
           
remplirChamps           
        ()

    {

        Connection    
           
connectMySQL        =    
    null;

        Statement    
           
    ordreMySQL       
    =         null;

        ResultSet    
           
        resultat   
           
    =         null;

       
ResultSetMetaData       
métaOrdre           
=        null;

       

        //chargement du pilote JDBC MySQL

        try

        {

            Class.forName("com.mysql.jdbc.Driver");

        }

        catch (ClassNotFoundException aSQLE)

        {

           
JOptionPane.showMessageDialog    (null, "Impossible de
charger le pilote de la base de données", "Erreur",
JOptionPane.ERROR_MESSAGE);

        }

       

        //connexion à la bdd

        try

        {

            connectMySQL =
DriverManager.getConnection ("jdbc:mysql://localhost/CLE_DE_SOL",
"root", "");

        }

        catch (SQLException aSQLE)

        {

           
JOptionPane.showMessageDialog    (null, "Impossible de
se connecter à la base de données\nVeuillez vérifier son état",
"Erreur", JOptionPane.ERROR_MESSAGE);

        }

       

        //création de l'ordre SQL

        try

        {

            ordreMySQL = connectMySQL.createStatement();

        }

        catch (SQLException aSQLE)

        {

           
JOptionPane.showMessageDialog    (null, "Impossible de
créer l'ordre SQL\n" + aSQLE.getMessage (), "Erreur",
JOptionPane.ERROR_MESSAGE);

        }

       

        // Lecture des résultats d'un ordre SQL

        try

        {

            resultat =
ordreMySQL.executeQuery ("select PRODUIT, MARQUE, MODELE, NUMERO,
PRIX_HT, QUANTITE, VENDEUR, PAGE, LIGNE from INVENTAIRE where ID='" +
this.idEffacer + "'");

        }

        catch (SQLException aSQLE)

        {

           
JOptionPane.showMessageDialog    (null, "Echec lors de
l'exécution de l'ordre SQL\n" + aSQLE.getMessage(), "Erreur",
JOptionPane.ERROR_MESSAGE);

        }

       

        // Obtention des résultats

        try

        {

            métaOrdre = resultat.getMetaData ();

            while (resultat.next())

            {

           
    for (int colonne = 1; colonne <=
métaOrdre.getColumnCount (); colonne++)

                {

           
        switch    (colonne)

                    {

           
           
case    1    :

           
           
           
    this.monTextProduit.setText   
(resultat.getString(colonne));

           
           
           
    break;

           
           
case    2    :

           
           
           
    this.monTextMarque.setText   
(resultat.getString(colonne));

           
           
           
    break;

           
           
case    3    :

           
           
           
    this.monTextModèle.setText   
(resultat.getString(colonne));

           
           
           
    break;

           
           
case    4    :

           
           
           
    this.monTextNumSérie.setText   
(resultat.getString(colonne));

           
           
           
    break;

           
           
case    5    :

           
           
           
    this.monTextPrixHT.setText   
(resultat.getString(colonne));

           
           
           
    break;

           
           
case    6    :

           
           
           
    this.monTextQuantité.setText   
(resultat.getString(colonne));

           
           
           
    break;

           
           
case    7    :

           
           
           
    this.monTextVendeur.setText   
(resultat.getString(colonne));

           
           
           
    break;

           
           
case    8    :

           
           
           
    this.monTextPage.setText   
(resultat.getString(colonne));

           
           
           
    break;

           
           
case    9    :

           
           
           
this.monTextLigne.setText   
(resultat.getString(colonne));

           
           
            break;

                    }

                }

            }

        }

        catch (SQLException aSQLE)

        {

           
JOptionPane.showMessageDialog    (null, "Echec lors de
la lecture des résultats\n" + aSQLE.getMessage(), "Erreur",
JOptionPane.ERROR_MESSAGE);

        }

       

        //fermeture de la connexion

        try

        {

            connectMySQL.close ();

        }

        catch (SQLException aSQLE)

        {

           
JOptionPane.showMessageDialog    (null,  "Erreur
lors de la fermeture de la connexion à la base de données\n" +
aSQLE.getMessage(), "Erreur", JOptionPane.ERROR_MESSAGE);

        }

       

        this.vérifPrix   
           
           
        (this.monTextPrixHT);

       

        connectMySQL   
    =         null;

        ordreMySQL   
        =   
     null;

        resultat   
           
    =         null;

        métaOrdre   
        =   
    null;

        System.gc();

    }





don't cross the crocked step
0
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
9 juil. 2007 à 15:44
Oula, c'est pas comme cà qu'on ferme la connection à une base !

Il faut d'abord fermer le resultset, puis le statement et enfin la connection !

métaOrdre.close();

resultat.close();

ordreMySQL.close();

connectMySQL.close();
0
mdrcedrick Messages postés 54 Date d'inscription dimanche 12 septembre 2004 Statut Membre Dernière intervention 22 novembre 2007
9 juil. 2007 à 15:50
voilà j'ai tout fermé sauf métaOrdre car la méthode close() n'existe pas pour un ResultsetMetaData

mais j'ai toujours cette conso de mémoire

avant de lancer la première fenetre je suis environs à 20Mo

une fois lancée je passe à peu près à 26Mo

et une fois tout fermé etc etc je reste à 26Mo


don't cross the crocked step
0
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
9 juil. 2007 à 15:54
je te dis, utilise un outil de profilling (JProfiler par exemple, mais il est payant) pour voir d'où vient ta fuite mémoire.
0
cs_GodConan Messages postés 2113 Date d'inscription samedi 8 novembre 2003 Statut Contributeur Dernière intervention 6 octobre 2012 12
9 juil. 2007 à 19:22
il n y a aucun soucis à mes yeux ;o)
la JVM s alloue de la memoire a concurrence de 64Mo (pas tout a fait sur du nombre exacte) et elle descide qd elle veux (algo compliqué  ;o) )  de la libérer   mais en fait cela au yeux du programe car elle la conserve au regard de l os pour en disposer plus rapidement la foie suivante cela fait parti des obtimisations... ;o) il te faut couper la jvm pour recupérer la memoire

ensuite pour ce qui est des "close" et bien normalement la fermeture de la connection entraine la fermeture des result et statement ;o) cependant ;o) cela reste une bonne habitude ;o) de les fermer explicitement pour assurer la bonne structure des methodes et class ....

Bon courage ;o)

GodConan ;o)
0
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
9 juil. 2007 à 19:29
heu... godconan : s'il force le garbage collector, en théorie, il devrait quand même récupèrer la mémoire qui n'est plus utilisée, non ?
0
cs_GodConan Messages postés 2113 Date d'inscription samedi 8 novembre 2003 Statut Contributeur Dernière intervention 6 octobre 2012 12
9 juil. 2007 à 21:29
NON ...  ;o) justement l astuce reside la .. ;o) cela coute chere en temps de demander des aloc à l OS donc la JVM ne libere pas systematquement la memoire pour pouvoir la réutiliser à volonté sans demander à l OS ...
la limite par defaut est de 64 Mo pour l application

GodConan ;o)
0
cs_GodConan Messages postés 2113 Date d'inscription samedi 8 novembre 2003 Statut Contributeur Dernière intervention 6 octobre 2012 12
9 juil. 2007 à 21:32
Et j oubliai ;o) farnchement la nécéssité de faire appele au GC est de plus en plus douteuse... ;o)

GodConan ;o)
0
mdrcedrick Messages postés 54 Date d'inscription dimanche 12 septembre 2004 Statut Membre Dernière intervention 22 novembre 2007
10 juil. 2007 à 14:06
j'ai vu ca hier soir avec mon prof ...

donc en faite une fenetre, même en faisant un dispose() est toujours en mémoire

donc plutôt que d'en ouvrir une nouvelle à chaque fois, j'ouvre la même et j'appelle juste une méthode qui change son contenu


voilà tout



don't cross the crocked step
0
cs_GodConan Messages postés 2113 Date d'inscription samedi 8 novembre 2003 Statut Contributeur Dernière intervention 6 octobre 2012 12
10 juil. 2007 à 15:43
Bon ben tu n as pas compris en fait ;o) ....
Qu importe que tu en ouvres une nouvelle ou pas ;o) .... au bout du compte si tu fait des dispose ou des "déreferencements" ;o) la memoire occupé finira par se stabiliser...

ceci dit ;o) on peut facilement exploser la memoire ;o) avec l affichage d images... ;o)

GodConan ;o)
0
cs_GodConan Messages postés 2113 Date d'inscription samedi 8 novembre 2003 Statut Contributeur Dernière intervention 6 octobre 2012 12
10 juil. 2007 à 15:45
Et pour rebondir sur ton dernier mesage ... il vaut mieu rafraichir son contenu plutot que de le changer .. ;o)
et donc faire dependre son contenu de certaine variable...

GodConan ;o)
0
Rejoignez-nous