Tournez votre question. La vraie question motivante est dans quelles circonstances pouvons-nous éviter les coûts de collecte des ordures?
Eh bien, tout d'abord, quels sont les coûts de la collecte des ordures? Il y a deux coûts principaux. D'abord, vous devez déterminer ce qui est vivant ; cela nécessite potentiellement beaucoup de travail. Deuxièmement, vous devez compacter les trous qui se forment lorsque vous libérez quelque chose qui a été alloué entre deux choses encore en vie. Ces trous sont inutiles. Mais les compacter coûte cher aussi.
Comment éviter ces coûts?
De toute évidence, si vous pouvez trouver un modèle d'utilisation du stockage dans lequel vous n'allouez jamais quelque chose de longue durée, puis allouez quelque chose de courte durée, puis allouez quelque chose de longue durée, vous pouvez éliminer le coût des trous. Si vous pouvez garantir que pour un sous-ensemble de votre stockage, chaque allocation suivante est de plus courte durée que la précédente dans ce stockage, il n'y aura jamais de trous dans ce stockage.
Mais si nous avons résolu le problème des trous, nous avons également résolu le problème de la collecte des ordures . Avez-vous quelque chose dans ce stockage qui est toujours vivant? Oui. Tout a-t-il été alloué avant de durer plus longtemps? Oui - cette hypothèse est de savoir comment nous avons éliminé la possibilité de trous. Par conséquent, tout ce que vous devez faire est de dire "la dernière allocation est-elle en vie?" et vous savez que tout est vivant dans ce stockage.
Avons-nous un ensemble d'allocations de stockage où nous savons que chaque allocation suivante a une durée de vie plus courte que l'allocation précédente? Oui! Les cadres d'activation des méthodes sont toujours détruits dans l'ordre inverse de leur création car ils ont toujours une durée de vie plus courte que l'activation qui les a créés.
Par conséquent, nous pouvons stocker des trames d'activation sur la pile et savoir qu'elles n'ont jamais besoin d'être collectées. S'il y a une image sur la pile, l'ensemble des images en dessous est de plus longue durée, donc elles n'ont pas besoin d'être collectées. Et ils seront détruits dans l'ordre inverse de leur création. Le coût de la collecte des ordures est ainsi éliminé pour les trames d'activation.
C'est pourquoi nous avons le pool temporaire sur la pile en premier lieu: car c'est un moyen facile d'implémenter l'activation de la méthode sans encourir de pénalité de gestion de la mémoire.
(Bien sûr, le coût de la récupération de la mémoire à laquelle font référence les références sur les trames d'activation est toujours là.)
Considérons maintenant un système de flux de contrôle dans lequel les trames d'activation ne sont pas détruites dans un ordre prévisible. Que se passe-t-il si une activation de courte durée peut donner lieu à une activation de longue durée? Comme vous pouvez l'imaginer, dans ce monde, vous ne pouvez plus utiliser la pile pour optimiser la nécessité de collecter des activations. L'ensemble d'activations peut à nouveau contenir des trous.
C # 2.0 a cette fonctionnalité sous la forme de yield return
. Une méthode qui fait un rendement va être réactivée ultérieurement - la prochaine fois que MoveNext sera appelée - et quand cela se produit n'est pas prévisible. Par conséquent, les informations qui se trouveraient normalement sur la pile pour la trame d'activation du bloc d'itérateur sont stockées à la place sur le tas, où elles sont récupérées lors de la collecte de l'énumérateur.
De même, la fonctionnalité "async / attente" à venir dans les prochaines versions de C # et VB vous permettra de créer des méthodes dont les activations "céderont" et "reprendront" à des points bien définis lors de l'action de la méthode. Étant donné que les trames d'activation ne sont plus créées et détruites de manière prévisible, toutes les informations qui étaient auparavant stockées dans la pile devront être stockées dans le tas.
Ce n'est qu'un accident de l'histoire que nous avons décidé pendant quelques décennies que les langues avec des cadres d'activation créés et détruits de manière strictement ordonnée étaient à la mode. Étant donné que les langues modernes manquent de plus en plus de cette propriété, attendez-vous à voir de plus en plus de langues réifier les continuations sur le tas récupéré, plutôt que sur la pile.