OVH Cloud OVH Cloud

Gestion de la mémoire

8 réponses
Avatar
Thibaut Desmarest
Bonjour,

Mon problème est le suivant :

J'aimerais savoir de quelle façon on est censés gérer la mémoire en
java. Normallement c'est la VM qui se charge de tout, et le garbage
collector passe régulièrement pour garbagecollecter et tout va bien dans
le meilleur des mondes.

Mais si en allant voir dans le gestionnaire de windows on se rend compte
que la mémoire ne se libère pas au fur et à mesure (que l'on supprime
des JPanel par exemple :D), existe t'il un moyen "propre" de détruire un
objet (un JPanel au hasard :D).

Parcequ'il me semble que la méthode finalize() ca fait dresser les
cheveux sur la tête des javaïstes chevronnés, et en plus je viens
d'essayer et ça marchait même pas !! En faisant finalize() sur le JPanel
la mémoire ne se libérait pas...

La méthode propre consiste t'elle donc à s'assurer que tous les liens
vers ce JPanel ont été détruits ? (Faire confiance au garbage
collector). Ou y'a t'il une autre méthode ?

Dans le premier cas, mon deuxième problème est le suivant :

J'ai ajouté un JPanel dans un CardLayout avec la méthode add( new Carte() );

Donc aucune référence vers cette carte à priori. Dans ma méthode
fermerProprement(), je fais appel à ma méthode supprimerCarte(JPanel
carteASuppr) qui se contente de faire un remove (comme j'avais fait le add).

Ca marche bien au niveau de l'application, pas de probleme la carte a
bien disparu, je passe sur celle d'après etc, magnifique...

Mais c'est ces centaines de Ko que je ne vois pas disparaitre du
gestionnaire de tâches qui m'énervent. Où peut il bien y avoir une autre
référence à ce JPanel ?

Merci d'avance,


Thibaut

8 réponses

Avatar
Vincent Cantin
Bonjour,

Mon problème est le suivant :

J'aimerais savoir de quelle façon on est censés gérer la mémoire en
java. Normallement c'est la VM qui se charge de tout, et le garbage
collector passe régulièrement pour garbagecollecter et tout va bien dans
le meilleur des mondes.

Mais si en allant voir dans le gestionnaire de windows on se rend compte
que la mémoire ne se libère pas au fur et à mesure (que l'on supprime
des JPanel par exemple :D), existe t'il un moyen "propre" de détruire un
objet (un JPanel au hasard :D).


La memoire se libere belle et bien, mais dans la pile de la JVM seulement.
La JVM se garde cette memoire sous la patte au cas ou ca serait utile plus
tard.

Parcequ'il me semble que la méthode finalize() ca fait dresser les
cheveux sur la tête des javaïstes chevronnés, et en plus je viens
d'essayer et ça marchait même pas !! En faisant finalize() sur le JPanel
la mémoire ne se libérait pas...


normale.

finalize est appele par le systeme de la JVM sur l'objet juste avant de le
garbage collecter.
ca sert a rien de l'appeler soit-eme, sauf a faire des bugs.

La méthode propre consiste t'elle donc à s'assurer que tous les liens
vers ce JPanel ont été détruits ? (Faire confiance au garbage
collector).


non, pas du tout.

Ou y'a t'il une autre méthode ?


Faire confiance, et verifier que son programme ne garde pas de references
vers les objets, c'est tout.

Dans le premier cas, mon deuxième problème est le suivant :

J'ai ajouté un JPanel dans un CardLayout avec la méthode add( new
Carte() );


Donc aucune référence vers cette carte à priori. Dans ma méthode
fermerProprement(), je fais appel à ma méthode supprimerCarte(JPanel
carteASuppr) qui se contente de faire un remove (comme j'avais fait le
add).


Ca marche bien au niveau de l'application, pas de probleme la carte a
bien disparu, je passe sur celle d'après etc, magnifique...

Mais c'est ces centaines de Ko que je ne vois pas disparaitre du
gestionnaire de tâches qui m'énervent. Où peut il bien y avoir une autre
référence à ce JPanel ?

Merci d'avance,


de rien

Vincent




Thibaut


Avatar
Thibaut Desmarest
Vincent Cantin wrote:

La memoire se libere belle et bien, mais dans la pile de la JVM seulement.
La JVM se garde cette memoire sous la patte au cas ou ca serait utile plus
tard.


Ah ok, c'est bon à savoir, mais alors y'a t'il un moyen de savoir si la
mémoire prise par le JPanel a bel et bien été liberée ? Comment être sûr
que le garbage collector va passer sur cet objet ?

Parcequ'il me semble que la méthode finalize() ca fait dresser les
cheveux sur la tête des javaïstes chevronnés, et en plus je viens
d'essayer et ça marchait même pas !! En faisant finalize() sur le JPanel
la mémoire ne se libérait pas...



normale.

finalize est appele par le systeme de la JVM sur l'objet juste avant de le
garbage collecter.
ca sert a rien de l'appeler soit-eme, sauf a faire des bugs.


:D

mon deuxième problème est le suivant :

J'ai ajouté un JPanel dans un CardLayout avec la méthode add( new

Carte() );

Donc aucune référence vers cette carte à priori. Dans ma méthode
fermerProprement(), je fais appel à ma méthode supprimerCarte(JPanel
carteASuppr) qui se contente de faire un remove (comme j'avais fait le

add).

Ca marche bien au niveau de l'application, pas de probleme la carte a
bien disparu, je passe sur celle d'après etc, magnifique...

Mais c'est ces centaines de Ko que je ne vois pas disparaitre du
gestionnaire de tâches qui m'énervent. Où peut il bien y avoir une autre
référence à ce JPanel ?



La question ci dessus reste posée si quelqu'un a une idée.

Merci,

Thibaut


Avatar
pier.jourdan
La JVM ne rends jamais la memoire qui lui a ete allouee. Meme si elle
n'a plus besoin de tout ce qui lui est alloue, elle le garde au cas
ou...
Avatar
Mouloud Samadi
En ligne de commandes tape: java -X, et java -Xrunhprof: help, tu pourras
voir les possibilités de gestion de la mémoire et de profiling que t'offre
la JVM.
Tu peux par exemple fixer les tailles minimale et maximale de la pile de la
VM avec les arguments -Xms et -Xmx, c'est en testant ton application à
pleine charge que tu pourras determiner les paramétres optimaux, l'essentiel
est que tu n'ais pas de "swap" de mémoire vers le disque dur durant
l'exécution de ton application. Donner trop de mémoire à la JVM est
déconseillé, elle devient fainéante, la fréquence de passage de GC deviendra
trop faible mais GC prendra bcp plus de temps pour nettoyer et ...compacter
si nécessaire la mémoire et durant son passage ton application sera sur les
genoux.
Mouloud

"pierre" wrote in message
news:
La JVM ne rends jamais la memoire qui lui a ete allouee. Meme si elle
n'a plus besoin de tout ce qui lui est alloue, elle le garde au cas
ou...


Avatar
Thomas Nguyen
On Mon, 18 Oct 2004 13:19:37 +0200, Thibaut Desmarest wrote:

Vincent Cantin wrote:

La memoire se libere belle et bien, mais dans la pile de la JVM seulement.
La JVM se garde cette memoire sous la patte au cas ou ca serait utile plus
tard.


Ah ok, c'est bon à savoir, mais alors y'a t'il un moyen de savoir si la
mémoire prise par le JPanel a bel et bien été liberée ? Comment être sûr
que le garbage collector va passer sur cet objet ?



J'envisage bien une solution, mais c'est vraiment un bricolage pour te
rassurer.

Crées une WeakReference initialisé avec ton JPanel.
Ensuite, tu peux tester si l'objet à été collecté avec la méthode get().
Si get() retourne null, c'est que le garbage collector est passé
par là.

-- Thomas


Avatar
Sébastien
Thomas Nguyen wrote:
On Mon, 18 Oct 2004 13:19:37 +0200, Thibaut Desmarest wrote:


Vincent Cantin wrote:


La memoire se libere belle et bien, mais dans la pile de la JVM seulement.
La JVM se garde cette memoire sous la patte au cas ou ca serait utile plus
tard.


Ah ok, c'est bon à savoir, mais alors y'a t'il un moyen de savoir si la
mémoire prise par le JPanel a bel et bien été liberée ? Comment être sûr
que le garbage collector va passer sur cet objet ?




J'envisage bien une solution, mais c'est vraiment un bricolage pour te
rassurer.

Crées une WeakReference initialisé avec ton JPanel.
Ensuite, tu peux tester si l'objet à été collecté avec la méthode get().
Si get() retourne null, c'est que le garbage collector est passé
par là.

-- Thomas



Si c'est simplement pour t'assurer que le garbage collector est passé sur ton panel, tu peux très
bien mettre un print de debug dans le 'finalize()'.

Sébastien



Avatar
Thibaut Desmarest
Sébastien wrote:
Thomas Nguyen wrote:

On Mon, 18 Oct 2004 13:19:37 +0200, Thibaut Desmarest wrote:


Vincent Cantin wrote:


La memoire se libere belle et bien, mais dans la pile de la JVM
seulement.
La JVM se garde cette memoire sous la patte au cas ou ca serait
utile plus
tard.



Ah ok, c'est bon à savoir, mais alors y'a t'il un moyen de savoir si
la mémoire prise par le JPanel a bel et bien été liberée ? Comment
être sûr que le garbage collector va passer sur cet objet ?




J'envisage bien une solution, mais c'est vraiment un bricolage pour te
rassurer.

Crées une WeakReference initialisé avec ton JPanel.
Ensuite, tu peux tester si l'objet à été collecté avec la méthode get().
Si get() retourne null, c'est que le garbage collector est passé
par là.

-- Thomas



Si c'est simplement pour t'assurer que le garbage collector est passé
sur ton panel, tu peux très bien mettre un print de debug dans le
'finalize()'.

Sébastien


Ok, merci pour vos réponses, mais j'ai encore une question bête (de
débutant) :
C'est quoi une weakReference ? J'imagine un peu le principe mais comment
ça marche concrètement ?

Merci,

Thibaut




Avatar
Vincent Cantin
Ok, merci pour vos réponses, mais j'ai encore une question bête (de
débutant) :
C'est quoi une weakReference ? J'imagine un peu le principe mais comment
ça marche concrètement ?

Merci,

Thibaut


WeakReference ref = new WeakReference(myJpanel);

...

if (ref.get() == null)
{
System.out.println("myJpanel has been garbage collected.");
}


ok ?

Vincent