Savoir quand un objet est détruit.

Savoir quand un objet est détruit. - Java - Programmation

Marsh Posté le 29-01-2005 à 12:06:46    

Bonjour,
 
Je crée plusieurs instances d'une classe, et j'ai besoin à chaque moment de connaitre toutes les instances de cette classe.
 
j'ai créé une sorte de manager avec une struture de donnée static et à chaque construction j'ajoute ma nouvelle instance dedans.
 
je cherche maintenant à savoir quand une instance est détruite pour mettre à jour cette liste d'instance.
 
des idées pour comment je peut faire ça ?

Reply

Marsh Posté le 29-01-2005 à 12:06:46   

Reply

Marsh Posté le 29-01-2005 à 12:31:53    

Détruite ? C'est a dire plus référencé ou quand l'espace mémoire est libéré (par le GC ?)

Reply

Marsh Posté le 29-01-2005 à 12:56:24    

Si c'est l'option "plus référencé", beh

Code :
  1. if (myInstance == null)


 [:airforceone]


---------------
Now Playing: {SYNTAX ERROR AT LINE 1210}
Reply

Marsh Posté le 29-01-2005 à 14:59:56    

Si c'est libération de mémoire, voir de ce coté
http://java.sun.com/j2se/1.4.2/doc [...] finalize()

Reply

Marsh Posté le 29-01-2005 à 18:10:38    

Le truc c'est que si ton manager a une référence vers ton instance, elle est pas prete d'être détruite...

Reply

Marsh Posté le 29-01-2005 à 18:37:21    

patachou a écrit :

Si c'est libération de mémoire, voir de ce coté
http://java.sun.com/j2se/1.4.2/doc [...] finalize()

justement non. Comme tu n'a pas la garantie que finalize() sera appelé, tu ne peux pas te basé dessus pour des tâches critiques.

Reply

Marsh Posté le 29-01-2005 à 20:02:46    

R3g a écrit :

Le truc c'est que si ton manager a une référence vers ton instance, elle est pas prete d'être détruite...


 
oui je viens de me rendre compte de ce probleme  :)

Reply

Marsh Posté le 29-01-2005 à 21:24:55    

EpoK a écrit :

oui je viens de me rendre compte de ce probleme  :)


Implémente un système de pool alors. Ton manager se charge de créer et de déréférencer les instances sur base d'appels à ses méthodes getInstance() et release().
 
Ou qq ch comme ça.


---------------
Now Playing: {SYNTAX ERROR AT LINE 1210}
Reply

Marsh Posté le 30-01-2005 à 09:57:46    

sircam a écrit :

Implémente un système de pool alors. Ton manager se charge de créer et de déréférencer les instances sur base d'appels à ses méthodes getInstance() et release().
 
Ou qq ch comme ça.


 
je vois pas trop en quoi ca va regler le probleme ?  :??:

Reply

Marsh Posté le 30-01-2005 à 10:48:50    

Je ne suis pas sûr d'avoir bien saisi ton problème, donc n'hésite pas à m'en dire plus.
 
J'imagine que ton manager pourrait gérer tout ce qui concerne l'instanciation ET le déréférencement de tes "bidules".
 
Les autres classes n'instancient pas elles-mêmes ni ne déréférencent de "bidules", elles font pour cela appel à ton manager.
 
Si les autres classes respectent bien le contrat, 1°- en ne créant pas elles-même de "bidules" et 2°- en ne déréférençant pas de "bidules" obtenus via ton manager, tu connais à tout moment le nombre exact d'instances de "bidule" dans ton pool.
 
C'est bien ce que tu demandais, "à chaque moment de connaitre toutes les instances de cette classe".


Message édité par sircam le 30-01-2005 à 10:49:04

---------------
Now Playing: {SYNTAX ERROR AT LINE 1210}
Reply

Marsh Posté le 30-01-2005 à 10:48:50   

Reply

Marsh Posté le 30-01-2005 à 15:49:16    

tout dépend, si tu veux juste vérifier qu etun ne crées pas une fuite de mémoire, tu mets un System.out.println dans finalize().
 
si tu veux gérer finement le cycle de vie de tes objets, il te faut une opération (close ou dispose en général) signalant à l'instance sa fin de vie


---------------
trainoo.com, c'est fini
Reply

Marsh Posté le 31-01-2005 à 16:02:53    

ben de toutes façons, tel que c'est là les references seront jamais morte, vu que son "manager" les garde ...


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 31-01-2005 à 16:33:38    

Faut utiliser une WeakHashMap je crois pour faire en sorte que les objets référencés dans la Map s'ils ne sont référencés que par elle partiront au GC

Reply

Marsh Posté le 31-01-2005 à 16:35:24    

effectivement


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 31-01-2005 à 16:36:15    

et j'ai pas droit à mon :jap: :D


Message édité par machinbidule1974 le 31-01-2005 à 16:36:25
Reply

Marsh Posté le 31-01-2005 à 16:37:38    

oué bah il aura droit de toucher à weakbidule quand il saura utiliser un GC :o

Reply

Marsh Posté le 31-01-2005 à 16:41:42    

nraynaud a écrit :

oué bah il aura droit de toucher à weakbidule quand il saura utiliser un GC :o


euh, ou plutot quand il aura compris qu'il doit pas l'utiliser, mais qu'il comprendra comment ça marche :o


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 31-01-2005 à 16:41:51    

On ne peut pas aussi utiliser le principe de JDBC avec une Connection et un ConnectionWrapper ?? Ca permet d'éviter que le client du "manager" ait à appeler une méthode close() ou dispose() sur celui-ci ?
 

Reply

Marsh Posté le 31-01-2005 à 16:43:21    

j'ai pas tout compris, mais le close() c'est très bien.

Reply

Marsh Posté le 31-01-2005 à 16:49:22    

Sauf erreur:
 
Quand on veut récupérer une Connection auprès d'une Datasource (poolée), on appelle getConnection(). On n'appelle pas de méthode close() explicitement sur la Datasource pour "rendre" la Connection.  
 
Je crois que c'est parceque ce que la datasource retourne n'est pas une Connection mais un proxy sur une Connection (ConnectionWrapper). Quand le client de la datasource relâche la référence du proxy, la JVM détecte que l'objet est finalizable, le finalize, la méthode finalize() du proxy retourne explicitement la Connection dans le pool de la Datasource et le client n'a pas à se soucier de ça.

Reply

Marsh Posté le 31-01-2005 à 17:31:59    

Comme c'est beau.


---------------
Now Playing: {SYNTAX ERROR AT LINE 1210}
Reply

Marsh Posté le 02-02-2005 à 09:57:32    


 Surcharger la méthode finalize de la classe que tu veux "surveiller" ne te suffit pas ?
 
 protected void finalize() throws Throwable {
  try {
   // le code qui sera appeler lors de  la destruction
   // et qui te conviens pour ta "surveillance"
  }
  finally {
          super.finalize();
  }
 }
 
 

Reply

Marsh Posté le 02-02-2005 à 10:15:02    

rompi a écrit :

Surcharger la méthode finalize de la classe que tu veux "surveiller" ne te suffit pas ?


Faut voir qu'il parle bien de "destruction" au niveau de la JVM, et non pas de déréférencement dans l'application (et a priori, c'est la 2è option selon l'énoncé).
 
Parce que cette histoire de finalize pour relâcher des resources, c'est sympa et c'est confortable, mais c'est pas forcément très futé. Selon la charge, les paramètres et la stratégie du GC, le nettoyage se fera plus ou moins à brève échéance, mais il y a un décalage qui peut être gênant.
 
P.e. si l'instance est tout à fait déréférencée dans l'appli mais pas encore GC, le "manager" sera dans un état inconsistant, puisqu'il considérera l'instance comme encore présente, alors que celle-ci subira un clean-up dû au finalize peu de temps après.
 
Je te raconte pas le bordel potentiel.
 
De plus, dans des cas certes de moins en moins fréquents, le GC se met en marche un poil trop tard, conduisant au phénomène de thread starvation. Lui donner du boulot qu'on aurait pu faire avant avec une méthode "dispose", c'est mettre de l'huile sur le feu.
 
Finalize n'est pas un "destructor" et ne remplace pas un "free" ou un "delete" d'autres langages !


---------------
Now Playing: {SYNTAX ERROR AT LINE 1210}
Reply

Marsh Posté le 03-02-2005 à 11:00:14    

machinbidule1974 a écrit :

Sauf erreur:
 
Quand on veut récupérer une Connection auprès d'une Datasource (poolée), on appelle getConnection(). On n'appelle pas de méthode close() explicitement sur la Datasource pour "rendre" la Connection.


eux ... je crois pas dire de connerie en disant qu'il faut appeler le close() sur la connection et que c'est ça qui rend la connection au pool.
 
maintenant, j'imagine que par sécurité, c'est fait automatiquement dans le finalize(), mais si tu ne fais pas le close, y a plein de connections qui vont être "perdues" le temps que la jvm fasse le ménage à coup de GC.
C'est vraiment une mauvaise utilisation du pool : il va être obligé de s'agrandir alors qu'il y a des connections non-utilisées (en attente de finalisation).
 
 
ou bien j'ai mal compris ce que tu as dis  :??:


---------------
ma vie, mon oeuvre - HomePlayer
Reply

Marsh Posté le 03-02-2005 à 11:43:27    

Tu as peut-être raison, faudrait que je retrouve le bouquin dans lequel j'avais découvert ce mécanisme de fonctionnement des datasources...
 
Il me semblait que le problème d'EpoK était proche de ce que j'avais vu sur l'un de mes projets. On manipulait un objet nommé Datasource (! instanceof javax.sql.Datasource) dont on devait s'assurer que la méthode disable() était bien appellée pour éviter les fuites de mémoire.
 
Ces Datasources sont stockées en cache dans une Hashtable vidée à intervalles réguliers. Le problème, c'est que le cache quand il se vide n'appelle pas explicitement la méthode disable() sur la datasource. La solution consiste à "envelopper" la datasource dans un objet DatasourceWrapper qui est placé dans la Hashtable du cache. A la purge du cache, la méthode finalize() de DatasourceWrapper (appellée par la JVM)  appelle explicitement disable() sur l'objet datasource enveloppé.
 

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed