OVH Cloud OVH Cloud

free

13 réponses
Avatar
Sylfelin
Bonjour,

Développeur delphi depuis Delphi 3 je découvre c#.

Une choses m'intrique dans les cours que je lis.
Soit par exemple :

String[] MyList = new String[];

Dans aucun des exemples il y a une instruction du style MyList.Free;


C'est le garbace collection de dotnet qui se charge de libérer la
mémoire ?

Par soucis de proprété (et par habitude) peut'on forcer cette
libération ?

Merci




--
---
Sylfelin

10 réponses

1 2
Avatar
balmeyer
Oui, je crois que tu peux forcer cette libération en faisant :

MyList = null;

ce qui libère la ressource.

Et puis si tu veux forcer la "collecte des déchets" en faisant :

System.GC.Collect();
Avatar
Merlin
> Et puis si tu veux forcer la "collecte des déchets" en faisant :
System.GC.Collect();



ce qui est parfaitement déconseillé en raison des dégradations de
performances que cela peut créer car lancer le GC à la main remet à
zero les stats de celui-ci (répartition des 3 générations du GC avec
mapping sur les caches du microprocesseur).
A n'utiliser qu'avant de lancer un code très critique en temps pour
être sur que le GC ne se déclenche pas pendant le boulot de ce code,
sinon à ne jamais utiliser...

--

///3rL1n____
Avatar
Merlin
> Développeur delphi depuis Delphi 3 je découvre c#.



tu as raison :-)

Dans aucun des exemples il y a une instruction du style MyList.Free;



non en effet

C'est le garbace collection de dotnet qui se charge de libérer la mémoire ?



oui

Par soucis de proprété (et par habitude) peut'on forcer cette libération ?



non cela ne servirait à rien en plus


En revanche il est toujours nécessaire de relacher les ressources
autres que la mémoire (handles, ressources physiques...). Il y a donc
pour cela le support de IDisposable avec la méthode Dispose. Beaucoup
de classes implémentent aussi une fonction Close qui relâche la
ressource occupée (un fichier disque par exemple).
Tout cela car on ne peut pas être sur et certain que les destructeurs
seront appelés. Donc ne rien coder dedans...



--

///3rL1n____
Avatar
Arnaud Debaene
Merlin wrote:
Tout cela car on ne peut pas être sur et certain que les destructeurs
seront appelés. Donc ne rien coder dedans...



Les *finaliseurs*. Il n'y a pas de destructeurs en .NET!!! (en CIL, c'est la
méthode Finalize).

C'est une bêtise sans nom de que C# appelle çà des destructeurs et utilise
la même syntaxe que les destructeurs C++.

Arnaud
MVP - VC
Avatar
Paul Bacelar
Pour compléter la réponse de Merlin

"MyList = null;" ne fait que mettre une variable à null et n'appel pas de
mécanisme de libération des ressources.

Pour avoir un mécanisme proche du C++ le mot clé "using" permet d'utiliser
simplement l'interface IDisposable pour la gestion des ressources non
managées donc non gérées par le Garbage Collector.
--
Paul Bacelar
MVP VC++


"balmeyer" wrote in message
news:
Oui, je crois que tu peux forcer cette libération en faisant :

MyList = null;

ce qui libère la ressource.

Et puis si tu veux forcer la "collecte des déchets" en faisant :

System.GC.Collect();
Avatar
GG [MVP]
Bonjour,

C'est une bêtise sans nom de que C# appelle çà des destructeurs et utilise
la même syntaxe que les destructeurs C++.



Il fallait bien attirer ou contenter tout le monde et dieu en même temps.
:-)

--
Cordialement.
GG.
Avatar
balmeyer
Oui en effet, je précise ma réponse : voilà ce qu'il *faudrait*
faire si tu voulais absolument obtenir un comportement identique à
Delphi, mais en fait il n'est plus nécessaire d'effectuer cette
libération des ressources explicites en C# (ou en java).
Je suis d'accord avec ce que dit Merlin, l'interêt du Garbage
Collector est justement de ne pas être appelé par le code, mais par
le runtime. Cette gestion "sûre" de la mémoire est vraiment d'un
confort !

Tu n'as pas besoin d'effectuer un MyList = null, sauf si tu es limité
en mémoire et que tu veux au plus vite liberer une ressource, au
milieu d'un procédure, par exemple.
Avatar
Merlin
> Pour avoir un mécanisme proche du C++ le mot clé "using" permet d'utiliser
simplement l'interface IDisposable pour la gestion des ressources non
managées donc non gérées par le Garbage Collector.



complétons encore :-)

IDisposable permet juste à une classe de gérer la libération des
ressources externes (autres que la mémoire).
Même après un appel à Dispose (ce que fait le using dans ce contexte en
effet) la mémoire n'est pas libérée, juste les ressources relachées par
le code de Dispose.
Il faudra dans tous les cas attendre que le runtime déclenche un cycle
de GC pour que la mémoire liée à l'instance soit libérée.

--

///3rL1n____
Avatar
Merlin
> Les *finaliseurs*. Il n'y a pas de destructeurs en .NET!!! (en CIL, c'est la
méthode Finalize).
C'est une bêtise sans nom de que C# appelle çà des destructeurs et utilise la
même syntaxe que les destructeurs C++.



je ne suis pas tout à fait de ton avis. C# n'a pas été conçu pour .NET
(on le voit aussi à la syntaxe complète sur les pointeurs pourtant
unsafe sous .NET).
De fait, le langage implémente bien le concept de destructeur.
C'est sous la plate-forme .NET qu'il se trouve que ces destructeurs ne
sont pas appelés de façon certaine, en raison de la gestion
particulière de la mémoire.
Maintenant on peut les appeler comme on veut, de toute façon mieux vaut
ne pas s'en servir alors... :-)

--

///3rL1n____
Avatar
Arnaud Debaene
Merlin wrote:
Les *finaliseurs*. Il n'y a pas de destructeurs en .NET!!! (en CIL,
c'est la méthode Finalize).
C'est une bêtise sans nom de que C# appelle çà des destructeurs et
utilise la même syntaxe que les destructeurs C++.



je ne suis pas tout à fait de ton avis. C# n'a pas été conçu pour .NET
(on le voit aussi à la syntaxe complète sur les pointeurs pourtant
unsafe sous .NET).
De fait, le langage implémente bien le concept de destructeur.
C'est sous la plate-forme .NET qu'il se trouve que ces destructeurs ne
sont pas appelés de façon certaine, en raison de la gestion
particulière de la mémoire.


Et c'est pour çà qu'il s'appellent des finaliseurs, et pas des
destructeurs;-)

Le seul langage .NET qui implémente les destructeurs, c'est C++/CLI grâce à
la "stack semantic".

Maintenant on peut les appeler comme on veut, de toute façon mieux
vaut ne pas s'en servir alors... :-)



Malheureusement, appeler çà avec le même nom qu'un autre concept proche mais
subtilement et fondamentalement différent dans un langage extrêmement connu
(C++ natif), c'est une source de confusions sans fin qui ne se justifie que
par une accroche commerciale de bas étage.

Arnaud
MVP - VC
1 2