OVH Cloud OVH Cloud

Destruction d'objet

8 réponses
Avatar
Sylvain MALLEVAL
bonjour,

je m'interroge sur la destructions des objets dans vb.net

si j'ai la procédure suivante

public sub Procedure()
dim Obj as new object
end sub

Est ce que l'objet est automatiquement détruit à la sortie de la procédure
ou est ce que je dois faire :
Obj.dispose : Obj = nothing


Merci
Sylvain

8 réponses

Avatar
Fred
Bonjour,
Je pense que ton objet n'est pas détruit car tu as pu l'affecter à autre
chose avant de sortir de la procédure. Par exemple l'ajouter à une
collection globale.
Maintenant , sur un bout de code aussi simple, peut-être que le compilateur
détecte que l'objet ne sert à rien et fait un dispose ;-)

"Sylvain MALLEVAL" <devbnet@[antispam]free.fr> a écrit dans le message de
news: #
bonjour,

je m'interroge sur la destructions des objets dans vb.net

si j'ai la procédure suivante

public sub Procedure()
dim Obj as new object
end sub

Est ce que l'objet est automatiquement détruit à la sortie de la procédure
ou est ce que je dois faire :
Obj.dispose : Obj = nothing


Merci
Sylvain




Avatar
Bruno Jouhier [MVP]
Il faut distinguer 3 cas

A) L'objet implément IDisposable (en principe, parce qu'il référence une
ressource non managée qui doit être libérée explicitement). Dans ce cas, il
faut que tu appelles obj.Dispose quand tu as fini d'utiliser l'objet.
Typiquement le code ressemblera à:

dim obj as new DisposableClass()
try
...
finally
obj.Dispose

(le finally est là pour garantir que le Dispose est fait même si le
traitement du block try lance une exception).

Note: l'appel à Dispose ne libère pas l'objet lui-même, il libère la
ressource non managée qui est associée à l'objet. La mémoire occupée par obj
sera récupérée plus tard par le garbage collector.

B) L'objet n'implémente pas IDisposable. Dans ce cas, il ne faut rien faire.
Pas la peine de faire Obj = nothing, ça ne sert à rien, juste à écrire du
code inutile. La mémoire de l'objet sera récupérée plus tard par le garbage
collector.

C) L'objet n'est pas un objet mais une valeur (une instance d'un
struct/ValueType). Dans ce cas le new l'aura alloué sur la pile (stack) et
non pas sur le tas (heap), et il sera immédiatement libéré (comme toutes les
variables qui sont sur la pile) à la fin de la méthode.

Bruno.

"Sylvain MALLEVAL" <devbnet@[antispam]free.fr> a écrit dans le message de
news: %
bonjour,

je m'interroge sur la destructions des objets dans vb.net

si j'ai la procédure suivante

public sub Procedure()
dim Obj as new object
end sub

Est ce que l'objet est automatiquement détruit à la sortie de la procédure
ou est ce que je dois faire :
Obj.dispose : Obj = nothing


Merci
Sylvain




Avatar
Patrick Philippot
Sylvain MALLEVAL wrote:
si j'ai la procédure suivante

public sub Procedure()
dim Obj as new object
end sub

Est ce que l'objet est automatiquement détruit à la sortie de la
procédure ou est ce que je dois faire :
Obj.dispose : Obj = nothing



Bonjour,

En complément à ce qu'a déjà dit Bruno, j'ajouterai quelques détails...

1. Ce qu'il est important de comprendre avec le Garbage Collector de
.Net, c'est que l'on ne maîtrise pas le moment de la destruction
effective de l'objet. Et donc le moment où la méthode Finalize sera
appelée. C'est automatique mais non déterministe. Si l'objet s'est
alloué des ressources qui coûtent cher et qui sont libérées
explicitement dans la méthode Finalize, cela peut être gênant. Si
l'objet a vécu très longtemps, il sera probablement passé en Génération
2 au niveau du GC et il se passera d'autant plus de temps avant qu'il ne
soit libéré (cela peut se chiffrer en minutes, voire en heures...).

2. Pour éviter ce problème, on peut décider d'implémenter dans cet objet
la méthode IDisposable. On utilise la méthode Dispose pour nettoyer
l'objet (mais il faut que cet appel soit fait explicitement par le code
utilisateur - sauf dans certaisn cas). Cela doit être documenté. Il est
fondamental dans ce cas d'appeler GC.SuppressFinalize sur l'objet
pendant l'exécution de Dispose pour que le GC n'inscrive pas l'objet
dans la file d'attente des appels à Finalize quand il aura décidé de
détruire l'objet. Cela permettra à l'objet d'être détruit plus tôt.

--
Patrick Philippot - Microsoft MVP
MainSoft Consulting Services
www.mainsoft.fr
Avatar
Sylvain MALLEVAL
Merci pour vos explication, mais ca vrai que me palucher la doc me parait un
peut difficile surtout que ca à l'air pointu... Donc, en gros, le mieux
serait que je libère mes objets manuellement pour être sur que cela soit
fait... Comme ca au moins je suis tranquille...

Tous les treenodes, les datasets, les forms, etc... Une fois que j'ai fini
de les utiliser, je fais un dispose et un nothing, comme ça je suis sur que
ca disparais... le garbage ne sera là qu'au cas ou j'aurais oublier de tuer
un truc par inadvertance...

Merci encore pour votre aide

Sylvain


"Patrick Philippot" a écrit dans le
message de news:
Sylvain MALLEVAL wrote:
> si j'ai la procédure suivante
>
> public sub Procedure()
> dim Obj as new object
> end sub
>
> Est ce que l'objet est automatiquement détruit à la sortie de la
> procédure ou est ce que je dois faire :
> Obj.dispose : Obj = nothing

Bonjour,

En complément à ce qu'a déjà dit Bruno, j'ajouterai quelques détails...

1. Ce qu'il est important de comprendre avec le Garbage Collector de
.Net, c'est que l'on ne maîtrise pas le moment de la destruction
effective de l'objet. Et donc le moment où la méthode Finalize sera
appelée. C'est automatique mais non déterministe. Si l'objet s'est
alloué des ressources qui coûtent cher et qui sont libérées
explicitement dans la méthode Finalize, cela peut être gênant. Si
l'objet a vécu très longtemps, il sera probablement passé en Génération
2 au niveau du GC et il se passera d'autant plus de temps avant qu'il ne
soit libéré (cela peut se chiffrer en minutes, voire en heures...).

2. Pour éviter ce problème, on peut décider d'implémenter dans cet objet
la méthode IDisposable. On utilise la méthode Dispose pour nettoyer
l'objet (mais il faut que cet appel soit fait explicitement par le code
utilisateur - sauf dans certaisn cas). Cela doit être documenté. Il est
fondamental dans ce cas d'appeler GC.SuppressFinalize sur l'objet
pendant l'exécution de Dispose pour que le GC n'inscrive pas l'objet
dans la file d'attente des appels à Finalize quand il aura décidé de
détruire l'objet. Cela permettra à l'objet d'être détruit plus tôt.

--
Patrick Philippot - Microsoft MVP
MainSoft Consulting Services
www.mainsoft.fr




Avatar
Piotrek
> Tous les treenodes, les datasets, les forms, etc... Une fois que j'ai fini
de les utiliser, je fais un dispose et un nothing, comme ça je suis sur


que
ca disparais... le garbage ne sera là qu'au cas ou j'aurais oublier de


tuer
un truc par inadvertance...



Ok, L'esprit de la chose est inverse: le garbage collector degomme tout le
monde, toi tu dois te deplacer pour eliminer tous ceux que le garbage ne
peut pas eliminer seul: les ressources managees (connections, fichiers
ouverts...)
Avatar
Patrick Philippot
Sylvain MALLEVAL wrote:
Merci pour vos explication, mais ca vrai que me palucher la doc me
parait un peut difficile surtout que ca à l'air pointu... Donc, en
gros, le mieux serait que je libère mes objets manuellement pour être
sur que cela soit fait... Comme ca au moins je suis tranquille...



Bonjour,

Je n'ai pas été assez clair, je crois. Dans *tous les cas*, c'est le
garbage collector qui détruit l'objet et vous ne pouvez pas décider du
moment où il le fera. L'implémentation de l'interface IDispose ne sert
qu'à s'assurer de la libération *au plus tôt*, par un appel à Dispose,
des ressources *non managées* que l'objet se serait alloué. Il n'y a
*aucune* notion de libération manuelle des objets dans .Net. Tout ce que
vous pouvez faire à la rigueur est un GC.Collect mais ce n'est pas une
pratique recommandée.

Mettre une variable contenant une référence à un objet à Nothing ne fait
que signifier à .Net que l'on abandonne cette référence. Cela ne
provoque *en aucune manière* la destruction immédiate de l'objet de
manière certaine, même s'il n'existe aucune autre référence au même
objet ailleurs dans le programme.

--
Patrick Philippot - Microsoft MVP
MainSoft Consulting Services
www.mainsoft.fr
Avatar
Patrick Philippot
Patrick Philippot wrote:
Mettre une variable contenant une référence à un objet à Nothing ne
fait que signifier à .Net que l'on abandonne cette référence. Cela ne
provoque *en aucune manière* la destruction immédiate de l'objet de
manière certaine, même s'il n'existe aucune autre référence au même
objet ailleurs dans le programme.



Ceci est à tel point vrai que si vous créez ce que l'on appelle une
"weak reference" sur un objet, vous pouvez toujours le "ressusciter"
plus tard. Tant que le Garbage Collector n'est pas passé dessus, c'est
possible.

--
Patrick Philippot - Microsoft MVP
MainSoft Consulting Services
www.mainsoft.fr
Avatar
Bruno Jouhier [MVP]
"Sylvain MALLEVAL" <devbnet@[antispam]free.fr> a écrit dans le message de
news:
Merci pour vos explication, mais ca vrai que me palucher la doc me parait
un
peut difficile surtout que ca à l'air pointu... Donc, en gros, le mieux
serait que je libère mes objets manuellement pour être sur que cela soit
fait... Comme ca au moins je suis tranquille...



C'est un mauvais raisonnement. Il vaut mieux que vous essayez de comprendre
les explications qu'on essaie de vous donner, au lieu de conclure rapidement
que c'est trop pointu et de faire n'importe quoi. Sinon, ça sert à quoi
qu'on se décarcasse...

De toute façon, ça n'a pas de sens de "libérer manuellement" dans un
environnemnt managé. Ca n'est pas vous qui contrôlez la libération mémoire,
c'est le GC. Assigner null/Nothing à une variable locale juste avant de
sortir du bloc dans laquelle elle est déclarée, ça ne sert strictement à
rien. Assigner null/Nothing a une variable globale (statique) qui maintient
en vie un graphe d'objets, ça a du sens car ça permet au GC de nettoyer les
objets du graphe s'ils ne sont plus référencés par ailleurs, mais là non
plus ça ne provoque pas une libération immédiate de la mémoire.

Quant à mettre des Dispose partout, c'est une absurdité. S'il n'y a pas de
ressource non-managée associée à vos objets, vous allez écrire du code pour
rien, ralentir votre programme et de toute façon ça ne libérera pas la
mémoire occupée par vos objets (relisez la note dans mon explication du cas
A, ou les réponses de Patrick Philippot).

Bruno.


Tous les treenodes, les datasets, les forms, etc... Une fois que j'ai fini
de les utiliser, je fais un dispose et un nothing, comme ça je suis sur
que
ca disparais... le garbage ne sera là qu'au cas ou j'aurais oublier de
tuer
un truc par inadvertance...

Merci encore pour votre aide

Sylvain


"Patrick Philippot" a écrit dans le
message de news:
Sylvain MALLEVAL wrote:
> si j'ai la procédure suivante
>
> public sub Procedure()
> dim Obj as new object
> end sub
>
> Est ce que l'objet est automatiquement détruit à la sortie de la
> procédure ou est ce que je dois faire :
> Obj.dispose : Obj = nothing

Bonjour,

En complément à ce qu'a déjà dit Bruno, j'ajouterai quelques détails...

1. Ce qu'il est important de comprendre avec le Garbage Collector de
.Net, c'est que l'on ne maîtrise pas le moment de la destruction
effective de l'objet. Et donc le moment où la méthode Finalize sera
appelée. C'est automatique mais non déterministe. Si l'objet s'est
alloué des ressources qui coûtent cher et qui sont libérées
explicitement dans la méthode Finalize, cela peut être gênant. Si
l'objet a vécu très longtemps, il sera probablement passé en Génération
2 au niveau du GC et il se passera d'autant plus de temps avant qu'il ne
soit libéré (cela peut se chiffrer en minutes, voire en heures...).

2. Pour éviter ce problème, on peut décider d'implémenter dans cet objet
la méthode IDisposable. On utilise la méthode Dispose pour nettoyer
l'objet (mais il faut que cet appel soit fait explicitement par le code
utilisateur - sauf dans certaisn cas). Cela doit être documenté. Il est
fondamental dans ce cas d'appeler GC.SuppressFinalize sur l'objet
pendant l'exécution de Dispose pour que le GC n'inscrive pas l'objet
dans la file d'attente des appels à Finalize quand il aura décidé de
détruire l'objet. Cela permettra à l'objet d'être détruit plus tôt.

--
Patrick Philippot - Microsoft MVP
MainSoft Consulting Services
www.mainsoft.fr