46 votes

Collecte des déchets en C++ -- pourquoi?

Je continue d'entendre des gens se plaindre du fait que C++ n'a pas de ramasse-miettes. J'entends également que le comité des normes C++ envisage de l'ajouter au langage. J'ai peur de ne pas voir l'intérêt... utiliser le RAII avec des pointeurs intelligents élimine le besoin de cela, non ?

Ma seule expérience de la gestion de mémoire automatique était sur quelques ordinateurs familiaux bon marché des années quatre-vingts, où cela signifiait que le système se figeait pendant quelques secondes de temps en temps. Je suis sûr que cela s'est amélioré depuis, mais comme vous pouvez le deviner, cela ne m'a pas laissé une haute opinion.

Quels avantages la gestion des déchets pourrait-elle offrir à un développeur C++ expérimenté ?

68voto

paercebal Points 38526

Je continue d'entendre des gens se plaindre du fait que C++ n'a pas de ramasse-miettes.

Je suis tellement désolé pour eux. Sérieusement.

C++ a RAII, et je me plains toujours de ne pas trouver de RAII (ou un RAII castré) dans les langages avec ramasse-miettes.

Quels avantages la ramasse-miettes pourrait-elle offrir à un développeur C++ expérimenté ?

Un autre outil.

Matt J l'a très bien écrit dans son post (Ramasse-miettes en C++ -- pourquoi ?) : Nous n'avons pas besoin des fonctionnalités de C++ car la plupart d'entre elles pourraient être codées en C, et nous n'avons pas besoin des fonctionnalités de C car la plupart d'entre elles pourraient être codées en Assembleur, etc.. C++ doit évoluer.

En tant que développeur : Je me fiche de la GC. J'ai essayé à la fois la RAII et la GC, et je trouve la RAII largement supérieure. Comme l'a dit Greg Rogers dans son post (Ramasse-miettes en C++ -- pourquoi ?), les fuites de mémoire ne sont pas si terribles (du moins en C++, où elles sont rares si C++ est vraiment utilisé) pour justifier la GC au lieu de la RAII. La GC a une désallocation/finalisation non déterministe et est juste un moyen d'écrire un code qui ne se soucie pas des choix spécifiques de mémoire.

Cette dernière phrase est importante : Il est important d'écrire un code qui "ne se soucie pas". De la même manière en C++ RAII où nous ne nous soucions pas de la libération des ressources car la RAII le fait pour nous, ou pour l'initialisation des objets car le constructeur le fait pour nous, il est parfois important de simplement coder sans se soucier de qui est propriétaire de quelle mémoire, et de quel type de pointeur (partagé, faible, etc.) nous avons besoin pour ce morceau de code. Il semble y avoir un besoin de GC en C++. (même si personnellement je ne parviens pas à le voir)

Un exemple d'utilisation pertinente de la GC en C++

Parfois, dans une application, vous avez des "données flottantes". Imaginez une structure de données en forme d'arbre, mais personne n'est vraiment le "propriétaire" des données (et personne ne se soucie vraiment de quand exactement elles seront détruites). Plusieurs objets peuvent les utiliser, puis les jeter. Vous voulez qu'elles soient libérées lorsque personne ne les utilise plus.

L'approche en C++ consiste à utiliser un pointeur intelligent. Le boost::shared_ptr vient à l'esprit. Ainsi, chaque morceau de données est détenu par son propre pointeur partagé. Cool. Le problème est que lorsque chaque morceau de données peut se référer à un autre morceau de données. Vous ne pouvez pas utiliser de pointeurs partagés car ils utilisent un compteur de référence, qui ne supportera pas les références circulaires (A pointe vers B, et B pointe vers A). Vous devez donc réfléchir beaucoup à l'endroit où utiliser des pointeurs faibles (boost::weak_ptr), et quand utiliser des pointeurs partagés.

Avec une GC, vous utilisez simplement les données structurées en arborescence.

L'inconvénient est que vous ne devez pas vous soucier quand les "données flottantes" seront vraiment détruites. Juste qu'elles le seront.

Conclusion

En fin de compte, si elle est bien faite, et compatible avec les idiomes actuels de C++, la GC serait un Autre Bon Outil pour C++.

C++ est un langage multiparadigme : Ajouter une GC fera peut-être pleurer certains fanboys de C++ à cause de la trahison, mais au final, ce pourrait être une bonne idée, et je suppose que le Comité des Standards C++ ne permettra pas à ce genre de fonctionnalité majeure de briser le langage, donc nous pouvons leur faire confiance pour faire le travail nécessaire pour permettre une GC C++ correcte qui n'interférera pas avec C++ : Comme toujours en C++, si vous n'avez pas besoin d'une fonctionnalité, ne l'utilisez pas et cela ne vous coûtera rien.

11voto

Matt J Points 15475

La réponse courte est que la collecte des déchets est très similaire en principe à RAII avec des pointeurs intelligents. Si chaque morceau de mémoire que vous allouez se trouve à l'intérieur d'un objet, et que cet objet est uniquement référencé par des pointeurs intelligents, vous avez quelque chose qui ressemble à la collecte des déchets (potentiellement mieux). L'avantage vient du fait de ne pas avoir à être si judicieux concernant la portée et le pointeur intelligent de chaque objet, et de laisser le runtime faire le travail pour vous.

Cette question semble analogue à "qu'est-ce que C++ a à offrir au développeur expérimenté en assembleur ? Les instructions et les sous-routines éliminent le besoin de cela, n'est-ce pas ?"

9voto

Greg Rogers Points 18119

Avec l'avènement de bons vérificateurs de mémoire tels que Valgrind, je ne vois pas beaucoup d'utilité à la collecte des déchets comme filet de sécurité "au cas où" nous aurions oublié de désallouer quelque chose - d'autant plus que cela n'aide pas beaucoup à gérer le cas plus générique des ressources autres que la mémoire (bien que celles-ci soient beaucoup moins courantes). De plus, allouer et désallouer explicitement de la mémoire (même avec des pointeurs intelligents) est assez rare dans le code que j'ai vu, puisque les conteneurs sont généralement un moyen beaucoup plus simple et meilleur.

Mais la collecte des déchets peut offrir des avantages en termes de performance potentiellement, surtout si beaucoup d'objets de courte durée de vie sont alloués sur le tas. La collecte des déchets offre également potentiellement une meilleure localité de référence pour les objets nouvellement créés (comparable à des objets sur la pile).

8voto

MSalters Points 74024

Le facteur de motivation pour le support du GC en C++ semble être la programmation lambda, les fonctions anonymes, etc. Il s'avère que les bibliothèques lambda bénéficient de la capacité d'allouer de la mémoire sans se soucier de la récupération. Le bénéfice pour les développeurs ordinaires serait des bibliothèques lambda compilant plus rapidement, plus simplement et de manière plus fiable.

Le GC aide également à simuler une mémoire infinie; la seule raison pour laquelle vous devez supprimer les POD est que vous devez recycler la mémoire. Si vous disposez du GC ou d'une mémoire infinie, il n'est plus nécessaire de supprimer les POD.

7voto

coppro Points 10692

Le comité n'ajoute pas la collecte des ordures, ils ajoutent quelques fonctionnalités qui permettent à la collecte des ordures d'être implémentée de manière plus sûre. Seul le temps dira s'ils ont effectivement un quelconque effet sur les compilateurs futurs. Les implémentations spécifiques pourraient varier largement, mais impliqueront probablement une collecte basée sur la reachability, ce qui pourrait entraîner un léger ralentissement, selon la manière dont c'est fait.

Une chose est sûre, cependant, aucun collecteur de déchets conforme aux normes ne pourra appeler les destructeurs - uniquement pour réutiliser silencieusement la mémoire perdue.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X