41 votes

Pourquoi la collecte des ordures quand RAII est disponible?

J'entends parle de C++14 l'introduction d'un garbage collector dans la norme C++ de la bibliothèque elle-même. Quelle est la justification de cette fonctionnalité? N'est-ce pas la raison qui RAII existe en C++?

  • Comment la présence de la bibliothèque standard du garbage collector affecter le RAII sémantique?
  • Comment est-il important pour moi(le programmeur) ou de la façon dont j'écris les programmes C++?

30voto

Ali Points 18740

La collecte des ordures et RAII sont utiles dans des contextes différents. La présence de la GC ne devrait pas affecter votre utilisation de RAII. Depuis le RAII est bien connu, je donne deux exemples où GC est à portée de main.


La collecte des ordures serait d'une grande aide dans la mise en œuvre sans verrouillage des structures de données.

[...] il s'avère que déterministe libérer de la mémoire est un problème fondamental dans sans verrouillage des structures de données. (à partir sans Verrouillage des Structures de Données Par Andrei Alexandrescu)

Fondamentalement, le problème est que vous devez vous assurer que vous ne sont pas la désallocation de la mémoire tout en un fil de la lecture. C'est là que GC devient à portée de main: Il peut voir les fils et ne faire que la libération de la mémoire quand il est sécuritaire. Veuillez lire l'article pour plus de détails.

Juste pour être clair: il ne veut pas dire que le MONDE ENTIER devrait être nettoyée comme en Java; que seules les données pertinentes doivent être nettoyés de façon précise.


Dans une de ses présentations, Bjarne Stroustrup a également donné un bon exemple où GC devient à portée de main. Imaginez une application écrite en C/C++, 10M SLOC dans la taille. L'application fonctionne assez bien, assez de bug), mais il ya des fuites. Vous n'ont ni les ressources (heures de travail), ni les connaissances fonctionnelles pour résoudre ce problème. Le code source est un peu bordélique du code legacy. Que faites-vous? Je suis d'accord que c'est peut-être le plus simple et le moins cher de balayer le problème sous le tapis avec le GC.


Comme il a été souligné par sasha.sochka, le garbage collector sera facultative.

Mon souci est que les gens commencent à l'aide de GC comme il est utilisé en Java et écrire bâclée code de ramassage des ordures et de recueillir tout. (J'ai l'impression qu' shared_ptr est déjà la valeur par défaut 'aller à', même dans les cas où l' unique_ptr ou, d'enfer, de l'allocation de pile serait-il le faire.)

11voto

sasha.sochka Points 4937

Je suis d'accord avec @DeadMG qu'il n'y a pas de GC actuel de la norme C++, mais je voudrais ajouter de la citation suivante de B. Stroustrup:

Quand (pas si) automatique de la collecte des déchets devient une partie de C++, il sera en option

Donc, Bjarne est sûr qu'il va être ajouté dans le futur. Au moins le président du groupe de travail d'experts (Évolution du Groupe de Travail) et l'un des plus importants membres du comité et, surtout, de la langue créateur) veut ajouter.

Sauf qu'il a changé d'avis, on peut s'attendre à être ajoutés et mis en œuvre dans l'avenir.

11voto

Cory Nelson Points 10540

Il y a quelques algorithmes qui sont compliquées/inefficace/impossible d'écrire sans un GC. Je suppose que c'est le point de vente majeur pour les GC en C++, et ne peut jamais le voir utilisé comme un usage général de l'allocateur.

Pourquoi pas un usage général de l'allocateur?

Tout d'abord, Nous avons RAII, et la plupart (dont moi) pensent que c'est une méthode supérieure de la gestion des ressources. Nous comme le déterminisme, car il permet d'écrire des solides, étanches code beaucoup plus simple et permet des performances prévisibles.

Deuxièmement, vous aurez besoin de placer quelques très des nations unies-C++comme des restrictions sur la façon dont vous pouvez utiliser de la mémoire. Par exemple, vous avez besoin d'au moins un accessible, onu-obfuscation pointeur. Obfuscation des pointeurs, comme le sont populaires dans les communes de l'arbre contenant les bibliothèques (à l'aide de l'alignement-bas garantis bits pour la couleur des drapeaux), entre autres, de ne pas être reconnaissable par le GC.

Lié à cela, les choses qui rendent moderne GCs donc utilisable vont être très difficile à appliquer pour C++ si vous soutien de tout nombre d'obfuscation des pointeurs. De générations en défragmentant les tables sont vraiment cool, parce que l'allocation est extrêmement bon marché (essentiellement juste incrémenter un pointeur) et éventuellement de votre allocations obtenir compactée dans quelque chose de plus petit avec l'amélioration de la localité. Pour ce faire, les objets doivent être mobiles.

Pour rendre un objet en toute sécurité mobile, le GC doit être en mesure de mettre à jour tous les liens vers elle. Il ne sera pas en mesure de trouver d'obfuscation ceux. Cela pourrait être accueillis, mais ne serait pas assez (probablement un gc_pin type ou similaire, utilisé comme courant std::lock_guard, qui est utilisé lorsque vous avez besoin d'un pointeur brut). La convivialité serait hors de la porte.

Sans faire les choses biens meubles, une table serait nettement plus lent et moins évolutive que ce que vous avez l'habitude d'ailleurs.

La convivialité raisons (gestion des ressources) et des raisons d'efficacité (rapide, mobiliers allocations) hors de la voie, quoi d'autre GC est bon? Certainement pas à usage général. Entrez sans verrouillage des algorithmes.

Pourquoi sans verrouillage?

Sans verrouillage des algorithmes de travail en laissant une opération en vertu de la prétention d'aller temporairement "out of sync" avec la structure des données et la détection/correction lors d'une étape ultérieure. L'une des conséquences de cela est que, en vertu de la prétention de la mémoire peut être consulté après qu'il a été supprimé. Par exemple, si vous avez plusieurs threads concurrents de la pop un nœud à partir d'un PRINCIPE, il est possible pour un seul thread à la pop et de supprimer le nœud avant qu'un autre thread a réalisé le nœud était déjà pris:

Thread:

  • Obtenir pointeur vers le nœud racine.
  • Obtenir pointeur au prochain nœud du nœud racine.
  • Suspendre

Le Fil B:

  • Obtenir pointeur vers le nœud racine.
  • Suspendre

Thread:

  • Pop nœud. (remplacer le nœud racine pointeur avec nœud suivant pointeur, si le nœud racine pointeur n'a pas changé depuis qu'il a été lu.)
  • Supprimer le nœud.
  • Suspendre

Le Fil B:

  • Obtenir pointeur au prochain nœud de notre pointeur de nœud racine, qui est maintenant "out of sync" et a été tout simplement supprimé et donc au lieu de nous bloquer.

À table, vous pouvez éviter la possibilité de lecture à partir de la mémoire non validées parce que le nœud ne sera jamais supprimé tandis que le Thread B est le référençant. Il y a des façons de contourner cela, comme le danger des pointeurs ou d'attraper SEH exceptions sur Windows, mais ceux-ci peuvent nuire à la performance de manière significative. GC a tendance à être la solution la plus optimale ici.

6voto

Puppy Points 90818

Il n'y a pas, car il n'existe pas. Les seules fonctionnalités C++ jamais eu de GC ont été introduits dans C++11 et ils sont juste marquage de la mémoire, il n'y a pas de collecteur nécessaire. Et il n'y aura dans le C++14.

Il n'existe aucun moyen en enfer un collectionneur pourrait passer Comité est, à mon avis.

4voto

andrei.hu Points 41

GC a les avantages suivants:

  1. Il peut gérer les références circulaires sans programmeur assistance (RAII de style, vous devez utiliser weak à briser les cercles). Ainsi, un RAII application de style peuvent encore "fuite" si elle est utilisée de façon abusive.
  2. Créer/détruire des tonnes de shared_ptr pour un objet donné peut être coûteux parce que le refcount incrémenter/décrémenter sont des opérations atomiques. Dans les applications multi-thread les emplacements de mémoire qui contient refcounts va être "chaud" des lieux, en mettant beaucoup de pression sur le sous-système mémoire. GC n'est pas sujette à cette question en particulier, car il utilise accessible définit à la place de refcounts.

Je ne dis pas que GC est le meilleur/bon choix. Je dis juste qu'il a des caractéristiques différentes. Dans certains scénarios qui pourraient être un avantage.

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