Je viens d'un environnement C++ et je travaille avec C# depuis environ un an. Comme beaucoup d'autres, je suis perplexe quant au fait que la gestion déterministe des ressources ne soit pas intégrée au langage. Au lieu de destructeurs déterministes, nous avons le modèle de disposable. Les gens commencent à se demander s'il vaut la peine de propager le cancer IDisposable dans leur code.
Dans mon cerveau biaisé par le C++, il semble qu'utiliser des pointeurs intelligents avec comptage de références et destructeurs déterministes soit un grand pas en avant par rapport à un ramasse-miettes qui nécessite l'implémentation de IDisposable et l'appel de Dispose pour nettoyer vos ressources autres que la mémoire. Admettons, je ne suis pas très intelligent... donc je pose la question uniquement dans le but de mieux comprendre pourquoi les choses sont comme elles sont.
Et si C# était modifié de manière à ce que :
Les objets soient comptés par référence. Lorsque le nombre de références d'un objet atteint zéro, une méthode de nettoyage des ressources est appelée de manière déterministe sur l'objet, puis l'objet est marqué pour le ramasse-miettes. Le ramassage des ordures se produit à un moment non déterministe à l'avenir, moment où la mémoire est récupérée. Dans ce scénario, vous n'avez pas à implémenter IDisposable ou à vous souvenir d'appeler Dispose. Vous implémentez simplement la fonction de nettoyage des ressources si vous avez des ressources autres que la mémoire à libérer.
- Pourquoi est-ce une mauvaise idée?
- Cela ne contredirait-il pas le but du ramasse-miettes?
- Serait-il possible de mettre en œuvre une telle chose?
ÉDIT: D'après les commentaires jusqu'à présent, c'est une mauvaise idée car
- Le ramasse-miettes est plus rapide sans comptage de références
- Problème de gestion des cycles dans le graphe d'objets
Je pense que le premier point est valable, mais le deuxième est facile à résoudre en utilisant des références faibles.
Alors, est-ce que l'optimisation de la vitesse l'emporte sur les inconvénients que vous:
- pourriez ne pas libérer une ressource non mémoire en temps opportun
- pourriez libérer une ressource non mémoire trop tôt
Si votre mécanisme de nettoyage des ressources est déterministe et intégré au langage, vous pouvez éliminer ces possibilités.
5 votes
Apple vient de annoncer que Objective C dans iOS 5 prendra en charge le "Comptage automatique des références". Tous les pointeurs Objective C sont automatiquement comptés et conservés/libérés. Cependant, Objective C prend toujours en charge la méthode dealloc qui vous donne un "destructeur" déterministe où vous pouvez libérer des ressources non liées à la mémoire et vous n'avez pas à utiliser IDisposable. Ils ont spécifiquement déclaré qu'ils ne prendront pas en charge un GC pour Objective C. Cela me semble être la bonne approche. À mon avis, Java et .NET se trompent sur ce point.
4 votes
Une chose à laquelle je m'inquiète en ce qui concerne GC est que les abonnés aux événements, même en mettant en œuvre des modèles d'événements faibles, continuent de recevoir des notifications tout en attendant d'être collectés par le ramasse-miettes. Cela rend obligatoire la mise en œuvre de IDisposable dans toutes les classes d'abonnés aux événements.
1 votes
Oui, et de la réponse acceptée : "Nous pensons qu'il est très important de résoudre le problème de cycle sans contraindre les programmeurs à comprendre, traquer et concevoir autour de ces problèmes de structures de données complexes." J'ai été rappelé de cela aujourd'hui alors que j'étais obligé de comprendre, traquer et concevoir autour des interactions complexes entre les structures de données et la durée de vie des objets afin de comprendre pourquoi la mémoire n'était pas libérée. Quelqu'un a oublié de disposer d'un objet qui se désabonne d'un gestionnaire d'événements global dans Dispose(). Les Extensions Réactives rendent tout jetable.
0 votes
Que voulez-vous dire par "ressource non mémorisée"?
0 votes
Un gestionnaire de fichier, un mutex, une référence au code natif. Toute ressource système allouée à votre processus qui nécessite un nettoyage autre que la mémoire.
1 votes
En ce qui concerne la raison #1 (GC est plus rapide sans le comptage de références), cette vitesse est relative. Nous avons conçu des systèmes qui gèrent des millions d'instances de classe longue durée en mémoire et nous avons constaté que les performances se dégradent considérablement (la construction du graphique accessible par le GC devient un problème majeur). Dans des cas comme celui-ci, le coût du comptage de références serait négligeable par rapport au coût de suivi des références. Nous avons recouru à a) migrer des classes vers des structures, de sorte que le conteneur n'ait besoin de suivre que la référence du tableau d'arrière-plan - et b) utiliser de la mémoire non managée. Votre proposition bénéficierait grandement à des cas comme le nôtre.