286 votes

Pourquoi ne pas le C++ ont un garbage collector?

Je ne suis pas poser cette question à cause des mérites de la collecte des ordures tout d'abord. Ma principale raison de la demande c'est que je sais que Bjarne Stroustrup a dit que C++ aura un garbage collector à un certain point dans le temps.

Cela dit, pourquoi n'a-t-il pas été ajouté? Il y a déjà quelques ramasseurs d'ordures pour le C++. Est-ce juste un de ces "plus facile à dire qu'à faire" type de choses? Ou existe-il d'autres raisons, il n'a pas été ajouté (et ne sera pas ajouté en C++11)?

La croix les liens:

EDIT: Juste pour préciser, je comprends les raisons pour lesquelles C++ n'ai pas de garbage collector quand il a été créé. Je me demandais pourquoi le collecteur ne peuvent pas être ajoutés.

171voto

Brian R. Bondy Points 141769

Implicite de collecte des ordures pourrait avoir été ajouté, mais il n'a tout simplement pas faire la coupe. Probablement en raison non seulement de la mise en œuvre des complications, mais aussi grâce à des gens de ne pas être en mesure de venir à un consensus général assez rapide.

Une citation de Bjarne Stroustrup lui-même (source):

J'avais espéré qu'un garbage collector ce qui pourrait éventuellement être activé serait une partie de C++0x, mais il y avait assez de problèmes techniques que j'ai à faire avec juste détaillé spécification de la façon dont un tel collecteur s'intègre avec le reste de la langue, si elle est fournie. Comme c'est le cas avec essentiellement toutes C++0x fonctionnalités, une mise en œuvre expérimentale existe.

Veuillez voir le lien ci-dessus pour plus de détails sur le pourquoi du GC est dur.

Il est également une bonne discussion sur le sujet ici.

Aperçu général:

C++ est très puissant et vous permet de faire presque n'importe quoi. Pour cette raison, il n'est pas automatiquement pousser beaucoup de choses sur vous qui pourrait influer sur les performances. La collecte des ordures peut être facilement mis en œuvre avec des pointeurs intelligents (les objets qui encapsulent des pointeurs avec un nombre de références, de suppression automatique d'eux-mêmes lorsque la référence du compte à rebours atteint 0).

C++ a été construit avec des concurrents dans l'esprit qui n'a pas de collecte des ordures. L'efficacité a été la principale préoccupation que le C++ n'a pour parer aux critiques en comparaison à C et les autres.

Il existe 2 types de collecte des ordures...

Explicite de collecte des ordures:

C++0x ont la collecte des ordures via des pointeurs créé avec shared_ptr

Si vous le voulez, vous pouvez l'utiliser, si vous ne voulez pas, vous n'êtes pas forcé de l'utiliser.

Vous pouvez actuellement utiliser boost:shared_ptr ainsi si vous ne voulez pas attendre pour C++0x.

Implicite de collecte des ordures:

Il n'a pas transparent de collecte des ordures. Il sera un point central pour l'avenir C++ spécifications.

Pourquoi Tr1 n'a pas implicite de collecte des ordures?

Il y a beaucoup de choses que tr1 de C++0x aurait dû, Bjarne Stroustrup dans de précédentes interviews a déclaré que tr1 n'avait pas comme beaucoup comme il l'aurait souhaité.

156voto

Matthieu M. Points 101624

Pour ajouter au débat ici.

Il y a des problèmes connus avec la collecte des ordures, et de les comprendre permet de comprendre pourquoi il n'y a aucune en C++.

1. La Performance ?

La première plainte est souvent question de performance, mais la plupart des gens n'ont pas vraiment conscience de ce qu'ils sont en train de parler. Comme l'illustre Martin Beckett le problème peut ne pas être la performance en soi, mais la prévisibilité de la performance.

Actuellement, il existe 2 familles de GC, qui sont largement déployés:

  • Mark-and-Sweep type
  • Référence de Comptage de type

L' Mark And Sweep est plus rapide (moins d'impact sur les performances d'ensemble) mais il souffre d'un "gel du monde" syndrome: c'est à dire lorsque le GC coups de pied dans, tout le reste est arrêté jusqu'à ce que le GC a fait son nettoyage. Si vous souhaitez créer un serveur qui répond en quelques millisecondes... certaines transactions ne sera pas à la hauteur de vos attentes :)

Le problème de la Reference Counting est différent: comptage de références ajoute-dessus, surtout en Multi-Threading environnements parce que vous devez avoir atomique comte. En outre il y a le problème des cycles de référence si vous avez besoin d'un algorithme intelligent pour détecter les cycles et les éliminer (généralement mise en œuvre par le "gel du monde" aussi, bien que moins fréquent). En général, à compter d'aujourd'hui, ce genre (même si normalement plus réactif, ou plutôt, le gel de moins en moins souvent) est plus lent que l' Mark And Sweep.

J'ai vu un papier par Eiffel maîtres d'œuvre qui ont essayé de mettre en œuvre un Reference Counting Garbage Collector qui sont similaires performance globale d' Mark And Sweep sans le "Gel Du Monde". Il faut un thread séparé pour le GC (typique). L'algorithme a été un peu effrayant (à la fin), mais le papier fait un bon travail de l'introduction des concepts à la fois et en montrant l'évolution de l'algorithme de la "simple" version à part entière. Lecture recommandée si seulement je pouvais mettre ma main sur le fichier PDF...

2. L'Acquisition De Ressources Est D'Initialisation

Il s'agit d'un idiome en C++ que vous enveloppez-la propriété des ressources à l'intérieur d'un objet pour s'assurer qu'ils sont correctement libérées. Il est principalement utilisé pour la mémoire puisque nous n'avons pas de collecte des ordures, mais il est aussi très utile quand même pour beaucoup d'autres situations:

  • les verrous (multi-thread, descripteur de fichier, ...)
  • connexions (pour une base de données, un autre serveur, ...)

L'idée est de bien contrôler la durée de vie de l'objet:

  • il devrait être en vie aussi longtemps que vous en avez besoin
  • il doit être tué lorsque vous avez terminé avec lui

Le problème de la GC, c'est que si elle contribue à l'ancienne et, finalement, des garanties plus tard... cette "ultime" peut ne pas être suffisant. Si vous relâche un verrou, vous voulez vraiment qu'il soit libéré, de sorte qu'il ne bloque pas les appels supplémentaires!

Langues avec GC avez deux solutions:

  • n'utilisez pas de GC, l'allocation de pile est suffisante: c'est normalement pour les problèmes de performances, mais dans notre cas, il aide vraiment car le champ d'application définit la durée de vie
  • using construire... mais c'est explicite (faible) RAII alors qu'en C++ RAII est implicite, de sorte que l'utilisateur NE peut pas involontairement font l'erreur (en omettant l' using mot-clé)

3. Pointeurs Intelligents

Pointeurs intelligents apparaissent souvent comme une balle d'argent à gérer la mémoire en C++. Souvent de fois j'ai entendu: nous n'avons pas besoin GC après tout, puisque nous avons des pointeurs intelligents.

On ne pouvait pas être plus faux.

Pointeurs intelligents faire aider: auto_ptr et unique_ptr utilisation RAII concepts, très utile en effet. Ils sont si simples que vous pouvez écrire vous-même très facilement.

Lorsqu'un besoin de partager la propriété toutefois, il devient de plus en plus difficile: vous risquez de partager entre plusieurs threads et il ya quelques questions subtiles avec la manipulation de la comte. Donc, on va naturellement vers shared_ptr.

C'est génial, c'est ce coup de pouce pour après tout, mais ce n'est pas une balle d'argent. En fait, le principal problème avec les shared_ptr , c'est qu'il émule un GC mis en œuvre par Reference Counting , mais vous avez besoin pour mettre en œuvre le cycle de détection de tous par vous-même... Urg

Bien sûr, il y a cette weak_ptr truc, mais j'ai malheureusement déjà vu des fuites de mémoire en dépit de l'utilisation de shared_ptr en raison de ces cycles... et quand vous êtes dans un environnement multithread, il est extrêmement difficile à détecter!

4. Quelle est la solution ?

Il n'y a pas de solution miracle, mais comme toujours, c'est certainement faisable. En l'absence de GC besoin d'être clair sur la propriété:

  • préfèrent avoir un seul propriétaire à un moment donné, si possible
  • si pas, assurez-vous que votre diagramme de classe n'a pas de cycle se rapportant à la propriété et à les briser avec de subtiles application de l' weak_ptr

Donc en effet, il serait bon d'avoir un GC... mais c'est pas une question triviale. Et dans le même temps, nous avons juste besoin de se retrousser les manches.

57voto

Martin Beckett Points 60406

Ce type? devrait-il être optimisé pour les systèmes embarqués machine à laver les contrôleurs, les téléphones portables, stations de travail ou les supercalculateurs?
Faut-il privilégier la réactivité de l'interface graphique ou la charge serveur?
faut-il utiliser beaucoup de mémoire ou il y a beaucoup de CPU?

C/c++ est utilisé dans de trop nombreuses circonstances différentes. Je soupçonne quelque chose comme des pointeurs intelligents de boost sera suffisant pour la plupart des utilisateurs

Edit - Automatique éboueurs ne sont pas tellement un problème de performance, vous pouvez toujours acheter plus de serveur) c'est une question d'être prévisible de la performance.
Ne sachant pas quand le GC va à coup de pied dans est comme employant un neuroleptique de pilote de ligne, la plupart du temps, ils sont grands, mais quand vous avez vraiment besoin de réactivité!

36voto

Greg Rogers Points 18119

L'une des plus grandes raisons que le C++ n'est pas construit dans la collecte des ordures est que l'obtention de la collecte des ordures à jouer gentil avec les destructeurs est vraiment, vraiment dur. Autant que je sache, personne ne sait vraiment comment le résoudre complètement encore. Il ya beaucoup de questions à traiter:

  • déterministe de la durée de vie des objets (comptage de référence vous donne ceci, mais le GC n'a pas. Même si elle ne peut être que grand d'une affaire).
  • qu'advient-il si un destructeur jette quand l'objet est d'ordures collectées? La plupart des langues ignorer cette exception, car il y a vraiment aucun bloc catch pour être en mesure de transport, mais ce n'est probablement pas une solution acceptable pour le C++.
  • Comment faire pour l'activer/la désactiver? Naturellement, il serait probablement un moment de la compilation décision, mais le code est écrit pour GC vs code qui est écrit pour ne PAS GC va être très différent et probablement incompatible. Comment conciliez-vous cela?

Ce sont quelques-uns des problèmes rencontrés.

16voto

Rayne Points 14518

Si vous souhaitez automatique de collecte des ordures, il y a des bonnes commercial et du domaine public, ramasseurs d'ordures, pour le C++. Pour les applications où la collecte des ordures est approprié, C++ est un excellent ordures collectées langue avec une performance qui se compare favorablement avec les autres déchets collectés langues. Voir Le Langage de Programmation C++ (3e Édition) pour une discussion de la collecte des ordures automatique en C++. Voir aussi, Hans-J. Boehm site pour C et C++ de collecte des ordures. Aussi, C++ prend en charge les techniques de programmation qui permet la gestion de la mémoire pour être en sécurité et de manière implicite, sans un garbage collector.

Source: http://www.stroustrup.com/bs_faq.html#garbage-collection

Quant à savoir pourquoi il ne l'a construit dans, Si je me souviens bien, il a été inventé avant le GC a été la chose, et je ne crois pas que la langue aurait pu avoir une GC pour plusieurs raisons(I. E vers l'Arrière de compatibilité avec le C)

Espérons que cette aide.

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