Quelle est la meilleure façon d'éviter l'utilisation de GC dans D? Existe-t-il un moyen d'utiliser des classes qui n'impliquent pas la gestion de leur mémoire, ou devez-vous utiliser des pointeurs vers des structures malloc'd comme vous le feriez en C et C++?Gestion de la mémoire non gérée dans D
Répondre
Il a été décidé il y a longtemps que les classes doivent être des types de référence en raison du slicing problem. D'un autre côté, D est un langage système. Par conséquent, l'utilisation de classes avec gestion manuelle de la mémoire est laide mais faisable.
Dans D2 + Phobos, vous pouvez (inutilement) allouer une instance de classe sur la pile en utilisant std.typecons.scoped()
. Vous pouvez (encore, unsafely) allouer une classe dans n'importe quel bloc de mémoire arbitraire en utilisant std.conv.emplace()
. Le bloc de mémoire dans lequel vous allouez la classe peut être créé, par exemple, en utilisant core.stdc.malloc()
. Toutefois, notez que vous devrez appeler GC.addRange()
si la classe peut contenir des pointeurs dans la mémoire allouée par le GC.
(Disclaimer: Je suis un programmeur D 1.0, pas tant D 2.0)
Au coeur, vous pouvez utiliser quelque fonction que vous voulez allouer de la mémoire en D. Dans D 1.0, vous pouvez override the new operator pour les classes et allouer leur mémoire comme bon vous semble; Je crois que cela est supprimé dans D 2.0, cependant.
Vous pouvez certainement utiliser la mémoire malloc pour une instance de classe, l'initialiser comme il convient, puis la convertir en une référence d'objet (attention à la référence du moniteur masqué).
Dans un cas plus extrême, vous pouvez toujours remplacer le GC avec une enveloppe de malloc qui vous oblige à gérer tout manuellement (même si je crois que seul D 1.0 + Tango rend ce moins que brutalement douloureuse.)
A À la fin de la journée, D ne se soucie pas de savoir comment ou où vos instances de classe sont allouées; une référence de classe est juste un pointeur dans une robe. N'utilisez simplement pas delete
sur un objet que vous n'avez pas alloué via new
.
IIRC, 'delete' est obsolète dans D2 –
Les deux réponses précédentes ont pris l'approche pour expliquer ce que sont les capacités de D et ce qu'elles ne sont pas, en ce qui concerne la gestion de la mémoire. Je ne suis pas sûr s'ils capturent l'essence de la question.
Mais en ce qui concerne la question de savoir comment réaliser facilement la gestion manuelle de la mémoire. Je dirais, utilisez la version C de malloc() et free() du std.c.stdlib. Tout ce qui est alloué par ceci, sera ignoré par le GC.
Surcharge de nouvelles pour vos classes, l'utilisation de C stdlib est une possibilité. Sinon, vous pouvez utiliser les données typeinfo pour enregistrer manuellement le tableau d'octets ClassInfo.init dans votre mémoire manuellement gérée. Appeler le ctor avec cette approche peut être difficile, mais vous pouvez simplement décider d'utiliser une fonction ordinaire au lieu du nom de ctor standard. Ensuite, enveloppez tout cela dans des modèles pratiques, et vous êtes prêt.
Note: Je suis aussi une personne D1.
Je suis curieux de savoir pourquoi vous avez spécifiquement besoin d'instances de classe gérées manuellement. N'essayant pas de vous abattre, je devrais juste comprendre avant que je puisse vraiment répondre. Y a-t-il une raison pour laquelle une structure ne conviendrait pas à vos besoins? Ces objets échappent-ils à la portée de leur création? Est-ce purement une question de création/destruction fréquente, où l'utilisation d'une liste libre pourrait être une solution?
Eh bien, j'ai besoin d'eux pour la même raison que vous avez besoin d'instances de classes collectées, c'est-à-dire que vous voulez un objet avec une sémantique de référence avec une durée de vie complexe. La partie de gestion manuelle de la mémoire concerne les problèmes de performance/utilisation de la mémoire. –
L'utilisation de la mémoire doit être la même, ou être très proche de ne faire aucune différence, que vous utilisiez la mémoire GC ou que vous la gériez manuellement. En ce qui concerne les performances, cela dépend de l'utilisation. Si ce sont les hits de performance dus à des allocations fréquentes, on peut facilement utiliser les listes libres. Si c'est la performance due aux balayages de GC, alors il n'y a pas beaucoup à faire - bien que même les classes allouées manuellement seront habituellement enregistrées pour la numérisation, à moins que vous soyez parfaitement sûr que ce n'est pas nécessaire. Avez-vous mesuré l'impact du GC sur votre cas, pour voir combien ça fait mal? –
Je ne vois pas ce que le problème de découpage a à voir avec la fabrication de mémoire non gérée. J'accepte le raisonnement pour en faire des types de référence, mais je veux juste pouvoir dire 'Foo a = new Foo(); ...; supprimer a; 'sans impliquer un GC. –
Vous ne pouvez pas faire cela en D2; il a été/sera spécifiquement retiré. Les plaintes directes à ce sujet à Andrei Alexandrescu. –
Vous ne pouvez pas faire quoi? Dsimcha a mentionné plusieurs choses. Êtes-vous en train de dire que 'scoped',' emplace' et 'malloc' ont été supprimés/dépréciés? EDIT: Oh, répondiez-vous à mon commentaire? Je suis conscient que 'delete' a été déprécié, mais la syntaxe n'est pas importante; Je voudrais juste un moyen d'allouer facilement de la mémoire et de la désallouer manuellement sans que le GC ne gêne le processus. –