OVH Cloud OVH Cloud

Method Finalize

15 réponses
Avatar
em
Bonjour à toutes et à tous,

J'ai un petit problème de compréhension ;-( Help me!!!!!! voici mon
problème:

Je viens de lire dans le MSDN qu'il ne fallait pas libérer d'objets managés
dans la méthode Finalize tels qu'une connection à une base de données.
Prenons par exemple un objet X qui ouvre un connexion à une bdd, et qui
possède une méthode Dispose() libèrant l'ensemble de la mémoire (y compris
celle de la bdd). Je suis d'accord que si j'appelle la méthode Dispose(),
toutes mes ressources vont être libérées.
Si un jour j'oublis d'appeler Dispose(), le rammase-miette prend le relais
et appelle la méthod Finalize.
Problème : étant donnée qu'il ne faut pas libérer une connexion bdd (d'après
MSDN) dans le destructeur, comment faire pour fermer ma connexion? se ferme
telle toute seule?

J'espère que j'ai était clair dans mes explications
Merci d'avance pour l'ensemble de vos réponse.

Man

5 réponses

1 2
Avatar
Bonjour,

le GC ne tourne pas de la même façon sur une page aspx et sur une appli
windows il crée un arbre des objets pouvant être collecté dans le cas d'une
page aspx l'arbre n'a qu'un niveau dans le cas d'une appli l'arbre a 2 ou 4
niveaux je sais plus exactement dans cet arbre le GC stocke les objet
pouvant être finalisé ensuite quand son thread reprend la main il détruit
les objets qui ne sont plus référencés par aucun autre objet.son thread a un
niveau faible on peut forcer le GC avec GC.collect() comme cela a été dit
cependant sur une page aspx comme l'arbre n'a qu'un niveau les objets son
détruit au deuxième passage autant dire en proportion d'un temps processeur
assez rapidement donc le GC.Collect() est certainement moins important que
dans une application.
la MSDN déconseille de fermer une connection a une base de données car si
une connection n'est plus utilisé elle part dans le pool d'ailleurs j'ai vu
une commande permettant d'interdire le pool de connection est de forcer à
n'utiliser qu'une connection. Donc MSDN déconseille la libération de la
connection car d'un cela gêne le pool et de deux il faudra attendre le GC
pour nettoyer.

Voilà c'était mon interprétation personnel

Sebastien

"em" a écrit dans le message de
news:
Bonjour à toutes et à tous,

J'ai un petit problème de compréhension ;-( Help me!!!!!! voici mon
problème:

Je viens de lire dans le MSDN qu'il ne fallait pas libérer d'objets


managés
dans la méthode Finalize tels qu'une connection à une base de données.
Prenons par exemple un objet X qui ouvre un connexion à une bdd, et qui
possède une méthode Dispose() libèrant l'ensemble de la mémoire (y compris
celle de la bdd). Je suis d'accord que si j'appelle la méthode Dispose(),
toutes mes ressources vont être libérées.
Si un jour j'oublis d'appeler Dispose(), le rammase-miette prend le relais
et appelle la méthod Finalize.
Problème : étant donnée qu'il ne faut pas libérer une connexion bdd


(d'après
MSDN) dans le destructeur, comment faire pour fermer ma connexion? se


ferme
telle toute seule?

J'espère que j'ai était clair dans mes explications
Merci d'avance pour l'ensemble de vos réponse.

Man




Avatar
Zazar
Aprés avoir fait le tour de ce que sais sur cette étape et de la maigre
documentation, j'apporte quelques précisions :
La documentation de Microsoft indique qu'il ne faut pas référencer les
autres objets managés depuis la méthode Finalize mais sans préciser
pourquoi.
En examinant le comportement du GC, on s'aperçoit qu'on a la garantie que
les objets référencés par notre objet en cours de destruction existent
encore (qu'ils implémentent une méthode Finalize ou non). Cependant, on a
aucun moyen de savoir si ils ont été "finalizés" ou non. Si on appelle
Dispose (ou une méthode équivalente) sur un objet déjà finalizé, on court le
risque que l'objet tente de libérer 2 fois une ressource non managée ou bien
qu'il lève une exception. Si on appelle Dispose sur un objet non finalizé,
on court le risque que les problèmes précédents soient rencontrés au moment
de la finalization de l'objet concerné. Et enfin, si l'objet est en cours de
finalization, vu qu'il n'a aucune raison d'implémenter un mécanisme de
synchronisation, il y a des chances pour que ça se passe encore plus mal :).
Conclusion : même si contrairement à ce que j'ai dit, les objets référencés
existent toujours, on ne peut rien faire avec.

--
Zazar
Avatar
Zazar
Bonjour

le GC ne tourne pas de la même façon sur une page aspx et sur une appli
windows



Le GC fonctionne de la même manière pour une application Web et une
application Windows.
il crée un arbre des objets pouvant être collecté dans le cas d'une
page aspx l'arbre n'a qu'un niveau dans le cas d'une appli l'arbre a 2 ou


4
niveaux je sais plus exactement



Non, vous confondez : le GC crée plusieurs arbres des objets n'étant pas à
collecter. Les niveaux de profondeur de ces arbres ne sont pas constants.
Les objets à collecter sont tous les objets existants ne faisant pas partie
de cet arbre.

dans cet arbre le GC stocke les objet
pouvant être finalisé



Non, les objets pouvant être finalisés sont maintenues dans une liste à part
(appelée freachable) . Cette liste est modifiée à chaque création d'objet,
chaque appel à GC.SuppressFinalize() et éventuellement lors des collectes

ensuite quand son thread reprend la main il détruit
les objets qui ne sont plus référencés par aucun autre objet.



et qui ne sont pas freachables.

son thread a un
niveau faible on peut forcer le GC avec GC.collect() comme cela a été dit
cependant sur une page aspx comme l'arbre n'a qu'un niveau les objets son
détruit au deuxième passage autant dire en proportion d'un temps


processeur
assez rapidement donc le GC.Collect() est certainement moins important que
dans une application.


Cette théorie se base sur un fonctionnement erroné du GC.

la MSDN déconseille de fermer une connection a une base de données car si
une connection n'est plus utilisé elle part dans le pool d'ailleurs j'ai


vu
une commande permettant d'interdire le pool de connection est de forcer à
n'utiliser qu'une connection. Donc MSDN déconseille la libération de la
connection car d'un cela gêne le pool et de deux il faudra attendre le GC
pour nettoyer.



Non plus :
Quand vous appelez la méthode Close d'un objet-connexion, celle-ci redevient
disponible pour le pool. Si vous n'appelez pas cette méthode, alors vous
allez devoir attendre le GC pour que la connexion redevienne disponible.

--
Zazar
Avatar
Merci de toutes ces précisions effectivement je vois que je faisais erreur
dans mon appréciation du GC

Cordialement
Sebastien
"Zazar" a écrit dans le message
de news:
Bonjour

> le GC ne tourne pas de la même façon sur une page aspx et sur une appli
> windows

Le GC fonctionne de la même manière pour une application Web et une
application Windows.
> il crée un arbre des objets pouvant être collecté dans le cas d'une
> page aspx l'arbre n'a qu'un niveau dans le cas d'une appli l'arbre a 2


ou
4
> niveaux je sais plus exactement

Non, vous confondez : le GC crée plusieurs arbres des objets n'étant pas à
collecter. Les niveaux de profondeur de ces arbres ne sont pas constants.
Les objets à collecter sont tous les objets existants ne faisant pas


partie
de cet arbre.

> dans cet arbre le GC stocke les objet
> pouvant être finalisé

Non, les objets pouvant être finalisés sont maintenues dans une liste à


part
(appelée freachable) . Cette liste est modifiée à chaque création d'objet,
chaque appel à GC.SuppressFinalize() et éventuellement lors des collectes

> ensuite quand son thread reprend la main il détruit
> les objets qui ne sont plus référencés par aucun autre objet.

et qui ne sont pas freachables.

> son thread a un
> niveau faible on peut forcer le GC avec GC.collect() comme cela a été


dit
> cependant sur une page aspx comme l'arbre n'a qu'un niveau les objets


son
> détruit au deuxième passage autant dire en proportion d'un temps
processeur
> assez rapidement donc le GC.Collect() est certainement moins important


que
> dans une application.
Cette théorie se base sur un fonctionnement erroné du GC.

> la MSDN déconseille de fermer une connection a une base de données car


si
> une connection n'est plus utilisé elle part dans le pool d'ailleurs j'ai
vu
> une commande permettant d'interdire le pool de connection est de forcer


à
> n'utiliser qu'une connection. Donc MSDN déconseille la libération de la
> connection car d'un cela gêne le pool et de deux il faudra attendre le


GC
> pour nettoyer.

Non plus :
Quand vous appelez la méthode Close d'un objet-connexion, celle-ci


redevient
disponible pour le pool. Si vous n'appelez pas cette méthode, alors vous
allez devoir attendre le GC pour que la connexion redevienne disponible.

--
Zazar




Avatar
em
Merci beaucoup pour ces précisions.
En gros, rien ne remplacera la libération de la mémoire explicite dans le
code. Le ramasse-miette semble être utilisé uniquement dans la cas où le
programme oubli de libérer la mémoire.





"Zazar" a écrit dans le message
de news:

Aprés avoir fait le tour de ce que sais sur cette étape et de la maigre
documentation, j'apporte quelques précisions :
La documentation de Microsoft indique qu'il ne faut pas référencer les
autres objets managés depuis la méthode Finalize mais sans préciser
pourquoi.
En examinant le comportement du GC, on s'aperçoit qu'on a la garantie que
les objets référencés par notre objet en cours de destruction existent
encore (qu'ils implémentent une méthode Finalize ou non). Cependant, on a
aucun moyen de savoir si ils ont été "finalizés" ou non. Si on appelle
Dispose (ou une méthode équivalente) sur un objet déjà finalizé, on court


le
risque que l'objet tente de libérer 2 fois une ressource non managée ou


bien
qu'il lève une exception. Si on appelle Dispose sur un objet non finalizé,
on court le risque que les problèmes précédents soient rencontrés au


moment
de la finalization de l'objet concerné. Et enfin, si l'objet est en cours


de
finalization, vu qu'il n'a aucune raison d'implémenter un mécanisme de
synchronisation, il y a des chances pour que ça se passe encore plus mal


:).
Conclusion : même si contrairement à ce que j'ai dit, les objets


référencés
existent toujours, on ne peut rien faire avec.

--
Zazar




1 2