206 votes

Quand est-il acceptable d’appels GC. Recueillir ?

Le conseiller général est que vous ne devez pas appeler GC.Collect de votre code, mais ce sont les exceptions à cette règle?

Je ne peux que penser à quelques cas très spécifiques où il peut faire sens pour forcer un garbage collection.

Un exemple qui vient à l'esprit est un service qui se réveille à intervalles, l'exécution de certaines tâches, et puis dort pendant une longue période. Dans ce cas, il peut être une bonne idée de forcer un collecter pour empêcher le bientôt-à-être-processus inactif à partir de maintenant sur plus de mémoire que nécessaire.

Existe-il d'autres cas où il est acceptable d'appel GC.Collect?

174voto

Jon Skeet Points 692016

Si vous avez de bonnes raisons de croire qu’un important ensemble d’objets, notamment ceux vous soupçonnez d’être dans les générations 1 et 2, sont désormais éligibles pour le garbage collection et qui maintenant serait le moment approprié pour recueillir en ce qui concerne les performances de petits touché.

Un bon exemple de ceci est que si vous avez fermé juste une grosse forme. Vous savez que tous les contrôles d’interface utilisateur peuvent être maintenant garbage collecté, et une très courte pause comme le formulaire est fermé probablement ne sera pas visible à l’utilisateur.

54voto

Marc Gravell Points 482669

J'utilise GC.Collect seulement lors de l'écriture brut/performance profiler bancs d'essai; c'est à dire que j'ai deux (ou plus) des blocs de code pour tester quelque chose comme:

GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
TestA(); // may allocate lots of transient objects
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
TestB(); // may allocate lots of transient objects
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
...

De sorte qu' TestA() et TestB() courir avec comme état similaire que possible - c'est-àdire TestB() n'a pas encore martelé juste parce qu' TestA à gauche, il est très proche du point de basculement.

Un exemple classique serait une simple console exe ( Main méthode de tri-assez pour être posté ici par exemple), qui montre la différence entre la boucle de concaténation de chaîne et StringBuilder.

Si j'ai besoin de quelque chose de précis, alors ce serait complètement indépendant de tests - mais souvent c'est suffisant si nous voulons juste de réduire (ou de normaliser) le GC pendant les tests à faire une bonne impression pour le comportement.

Au cours de la production de code? Je n'ai pas encore l'utiliser ;-p

33voto

Ian Ringrose Points 19115

La meilleure pratique est de ne pas forcer une collecte des ordures dans la plupart des cas. (Chaque système, j'ai travaillé sur de qui avait forcé la collecte des poubelles, avait en soulignant les problèmes qui, si elle est résolue aurait supprimé le besoin de forcé la collecte des ordures, et accéléré le système grandement.)

Il y a quelques cas, lorsque vous en savoir plus sur l'utilisation de la mémoire alors que le garbage collector. C'est peu probable dans un multi-utilisateur de l'application ou un service qui répond à plus d'une demande à la fois.

Toutefois, dans certains de lot type de traitement que vous en connaissez plus que le GC. E. g. imaginez une application.

  • Est donné une liste de noms de fichier sur la ligne de commande
  • Processus un seul fichier puis envoyer le résultat vers un fichier de résultats.
  • Pendant le traitement du fichier, crée beaucoup de l'interdépendance des objets qui ne peuvent pas être collectées jusqu'à ce que le traitement du dossier complet (par exemple, un arbre d'analyse)
  • Ne gardez pas de correspondance entre les fichiers qu'il a traitées.

Vous pouvez être en mesure de faire une affaire (après mûre) les tests que vous devez forcer un plein de collecte des ordures après avoir traiter chaque fichier.

Un autre cas est un service qui se réveille toutes les quelques minutes pour traiter de certains éléments, et de ne pas garder en l'état pendant qu'il est endormi. Alors forcement une collection complète juste avant d'aller dormir peut être utile.

Le seul moment où je considère forcer une collection, c'est quand je sais que beaucoup de l'objet a été créé récemment et très peu d'objets sont actuellement référencé.

Je préférerais avoir un garbage collection API quand j'ai pu lui donner des conseils sur ce type de chose, sans avoir à forcer un GC mon auto.

Voir aussi "Rico Mariani Performances de Tidbits"

24voto

Brian Points 82719

Un cas est quand vous essayez de code de test unitaire qui utilise WeakReference.

12voto

Joel Coehoorn Points 190579

Vous pouvez appeler GC.Collect() lorsque vous savez quelque chose sur la nature de l'application que le garbage collector n'est pas. Il est tentant de penser que, comme l'auteur, c'est très probable. Cependant, la vérité est que le GC montants pour un assez bien écrit et testé système expert, et il est rare que vous savez quelque chose sur le faible niveau des chemins de code qu'il n'a pas.

Le meilleur exemple que je peux penser de l'endroit où vous pourriez avoir quelques informations supplémentaires est une application que les cycles entre les périodes d'inactivité et de la période très chargée. Vous voulez le meilleur rendement possible pour la période très chargée et donc voulez utiliser le temps d'attente pour faire un peu de ménage.

Cependant, la plupart du temps, le GC est assez intelligent pour faire cela de toute façon.

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