J'ajouterai juste au poste de SaumonAgile, sur les generations. En moyenne, compter une collecte Gen0 toutes les 5 secs, et multiplier par 10 pour chaque gen au dessus. De fait, si un objet de gen 2 doit etre finalizé, le temps de liberation effective peut etre tres long.
Pour les sources, j'avoue preferer les bouquins (la en l'occurence ca venait de Essential .Net, volume 1 : The CLR), mais tu trouveras des articles interressants sur la msdn.
Disons pour resumer, qu'il peut arriver d'avoir à implementer un finalizer, mais qu'a chaque fois que cette obligation apparait, le Dispose doit l'etre aussi, ce qui permet si l'utilisateur, dans le cas d'une lib, ou le developpeur utilise correctement leurs disposes de diminuer le surcout induit des finalizers, tout en assurant une liberation garantie aux ressources tenues. Bref, en simplifiant à l'extreme, Dispose() doit etre considéré comme le destructeur en .Net, et machin.Dispose() correspond conceptuellement à delete machin;.
A noter enfin, ca peut etre etait deja dit, mais mieux vaut le savoir, qu'il ne faut jamais toucher à un membre managé dans un finalizer (le thread du finalizer invoquant les finalize dans un ordre non determiné, on peut obtenir des resultats surprenants).
Le GC passera toujours derriere toi, mais le facteur temps peut etre grandement optimisé. Sans plus de precautions, tu peux vite te retrouver avec des consos memoires en dents de scie (dues à des promotions incessantes), alors que tu pourrais avoir une conso beaucoup plus stable.
Le GC de .Net est une sacré machinerie, mais pour paraphraser un post d'un ng anglais, "ce n'est pas parce que tu as une femme de menage, qu'il faut se sentir obligé de mettre deux fois plus le souk." =p






Répondre avec citation


Effectivement, lock est un mot clef dans csharp et je ne le savais pas. Ok il s'utilise comme tu l'as dit, mon exemple est donc très mal choisi.



Partager